C# Optional Out Parameter - c#

Is there any way to make an out parameter of a method optional? I have a method that needs several parameters to return null most of the time, but sometimes they will have a value. I am trying to find out if there is a better way to accomplish this than by setting the values to null first, or setting them to null after the if/else. This may be the only way to do it, but it would be nice if there were optional out parameters or something equivalent. Here is the code:
private static void GetInitInfo(string initLine, string ncPointType, out double? relinquishDefault, out bool? ignoreRelinquishDefault, out bool? closedForStart, out bool? adjustDisabled)
{
relinquishDefault = null;
ignoreRelinquishDefault = null;
closedForStart = null;
adjustDisabled = null;
switch (ncPointType)
{
case "MSD":
adjustDisabled = LastToken<bool?>(initLine);
break;
case "BO":
relinquishDefault = SecondToken<double>(initLine);
closedForStart = ThirdToken<bool?>(initLine);
ignoreRelinquishDefault = !ForthToken<bool?>(initLine);//ignoreRelDef would be reverse of use initial value
break;
case "MSO":
closedForStart = SecondToken<bool?>(initLine);
relinquishDefault = ThirdToken<double>(initLine);
ignoreRelinquishDefault = !ForthToken<bool?>(initLine);//ignoreRelDef would be reverse of use initial value
break;
case "AD":
relinquishDefault = ThirdToken<double>(initLine);
ignoreRelinquishDefault = false;
break;
case "BD":
relinquishDefault = SecondToken<double>(initLine);
adjustDisabled = LastToken<bool?>(initLine);
ignoreRelinquishDefault = false;
break;
case "AOS":
relinquishDefault = FirstToken<double>(initLine);
ignoreRelinquishDefault = !ThirdToken<bool?>(initLine);//ignoreRelDef would be reverse of use initial value
break;
}
}

This isn't not allowed according to the C# 4.0 Spec: section 21.1.
A workaround is to overload with another method that does not have out or ref parameters.

I believe this question is asking about having to assign values inside the method with out parameters, and whether there is any way to circumvent that, i.e. by leaving the values unassigned rather than explicitly having to assign them null.
e.g. Do you have to write:
public bool OutMethod(out int? output)
{
output = null;
return true;
}
Or is there a way to do something like:
public bool OutMethod(out int? output)
{
return true;
}
With the same result?
Short answer is no, this can't be avoided. See the documentation for an example which includes assigning null explicitly, and states:
Note that the third argument is assigned to null. This allows methods to return values optionally.
Examples of this can also be found in the .NET framework. e.g. Dictionary<TKey,TValue>'s TryGetValue method:
public bool TryGetValue(TKey key, out TValue value)
{
int num = this.FindEntry(key);
if (num >= 0)
{
value = this.entries[num].value;
return true;
}
value = default(TValue);
return false;
}
Note the explicit assignment to default(TValue)

Use the overload with signature that does not have out parameters:
private static void GetInitInfo(string initLine, string ncPointType)
{
double? relinquishDefault;
bool? ignoreRelinquishDefault;
bool? closedForStart;
bool? adjustDisabled;
GetInitInfo( initLine, ncPointType, out relinquishDefault, out ignoreRelinquishDefault,
out closedForStart, out adjustDisabled);
}

The explanation is quite simple: You can do it. Just assign an out parameter inside the method to the desired value.
Now you can ask yourself, why can't we do that in the method signature? Well, let us have a look at the normal optional value parameters. They are assigned a predefined value if they are not assigned by the caller. So caller knows the value, which will be passed if the parameter is not set explicitly. It has a control of it and it is responsible for that decision.
Since the caller of the method is NOT responsible for the assignment of the out parameter, it makes no sense to offer a default value. The only thing you could achieve, by having a default out parameter value is to let the caller know what one of the possible values of that out parameter would be. But would that make sense? When will this value be used? Under what condition? All this is still hidden from the caller. So there is no real benefit from having an optional out parameter value, apart from having a possiblity to set it inside the signature instead of the method body.
So, having that said, the following would not make much sense:
public bool TrySomething(out string outObject = "default value") { ... }
However, what would be cool is to allow the following method
public bool TrySomething(out string outObject) { ... }
to be invoked as follows:
bool result = TrySomething();
And have that behind the scenes equivalent to:
string dummyWhichWillNeverBeUsed;
bool succeeded = TrySomething(out dummyWhichWillNeverBeUsed);
Unfortunately, that is not allowed.
And of course, as explained in other answers, you can always have overloads without out parameter.

Related

Modifying C# Out parameter more than once

When you have a function that has an out parameter is it best practice to create a new variable inside the function and assign the out parameter to it at the end of the function? Or give the out parameter some empty/default value in the beginning and modify throughout the function.
I'm trying to come up with some reasoning as to why one of these coding styles/practices is better to use.
Option 1: Using just the out parameter.
public bool SomeFunc(out string outStr)
{
outStr = "";
if (errorCond)
return false;
outStr += "foo";
outStr += "bar";
return true;
}
Option 2: Using a temporary variable.
public bool SomeFunc1(out string outStr)
{
string tempStr = "";
outStr = ""; // To prevent 'The out parameter must be set' error on return false line.
if (errorCond)
return false;
tempString += "foo";
tempString += "bar";
outStr = tempStr;
return true;
}
Even though both of these achieve the same outcome, which is preferable? Are there any drawbacks to either one of them?
Actually, it doesn't matter, you just must assign variable in this method.
But, it is preferable to avoid using output or reference parameters:
Working with members that define out or reference parameters requires
that the developer understand pointers, subtle differences between
value types and reference types, and initialization differences
between out and reference parameters.
For me, the second one is overhead
Assign a default value at the beginning of the method, and then change the value if necessary.
Look at examples in .net source codes, like int.TryParse or Enum.TryParse

C# - checking if a variable is initialized

I want to check if a variable is initialized at run time, programmatically. To make the reasons for this less mysterious, please see the following incomplete code:
string s;
if (someCondition) s = someValue;
if (someOtherCondition) s = someOtherValue;
bool sIsUninitialized = /* assign value correctly */;
if (!sIsUninitialized) Console.WriteLine(s) else throw new Exception("Please initialize s.");
And complete the relevant bit.
One hacky solution is to initialize s with a default value:
string s = "zanzibar";
And then check if it changed:
bool sIsUninitialized = s == "zanzibar";
However, what if someValue or someOtherValue happen to be "zanzibar" as well? Then I have a bug. Any better way?
Code won't even compile if the compiler knows a variable hasn't been initialized.
string s;
if (condition) s = "test";
// compiler error here: use of unassigned local variable 's'
if (s == null) Console.Writeline("uninitialized");
In other cases you could use the default keyword if a variable may not have been initialized. For example, in the following case:
class X
{
private string s;
public void Y()
{
Console.WriteLine(s == default(string)); // this evaluates to true
}
}
The documentation states that default(T) will give null for reference types, and 0 for value types. So as pointed out in the comments, this is really just the same as checking for null.
This all obscures the fact that you should really initialize variables, to null or whatever, when they are first declared.
With C# 2.0, you have the Nullable operator that allows you to set an initial value of null for heretofore value types, allowing for such things as:
int? x = null;
if (x.HasValue)
{
Console.WriteLine("Value for x: " + num.Value);
}
Which yields:
"Value for x: Null".
Just assign it null by default, not a string value
Here's one way:
string s;
if (someCondition) { s = someValue; }
else if (someOtherCondition) { s = someOtherValue; }
else { throw new Exception("Please initialize s."); }
Console.WriteLine(s)
This might be preferable for checking if the string is null, because maybe someValue is a method that can sometimes return null. In other words, maybe null is a legitimate value to initialize the string to.
Personally I like this better than an isInitialized flag. Why introduce an extra flag variable unless you have to? I don't think it is more readable.
You can keep a separate flag that indicates that the string has been initialized:
string s = null;
bool init = false;
if (conditionOne) {
s = someValueOne;
init = true;
}
if (conditionTwo) {
s = someValueTwo;
init = true;
}
if (!init) {
...
}
This will take care of situations when s is assigned, including the cases when it is assigned null, empty string, or "zanzibar".
Another solution is to make a static string to denote "uninitialized" value, and use Object.ReferenceEquals instead of == to check if it has changed. However, the bool variable approach expresses your intent a lot more explicitly.
I would agree with Vytalyi that a default value of null should be used when possible, however, not all types (like int) are nullable. You could allocate the variable as a nullable type as explained by David W, but this could break a lot of code in a large codebase due to having to refine the nullable type to its primitive type before access.
This generic method extension should help for those who deal with large codebases where major design decisions were already made by a predecessor:
public static bool IsDefault<T>(this T value)
=> ((object) value == (object) default(T));
If you are staring from scratch, just take advantage of nullable types and initialize it as null; that C# feature was implemented for a reason.
I pick initialization values that can never be used, typical values include String.Empty, null, -1, and a 256 character random string generator .
In general, assign the default to be null or String.Empty. For situations where you cannot use those "empty" values, define a constant to represent your application-specific uninitialized value:
const string UninitializedString = "zanzibar";
Then reference that value whenever you want to initialize or test for initialization:
string foo = UnininitializedString;
if (foo == UninitiaizedString) {
// Do something
}
Remember that strings are immutable constants in C# so there is really only one instance of UninitializedString (which is why the comparison works).

Why use out keyword instead of assignment in c#?

I've been investigating the out keyword in C# after reading the section about it in C# in Depth. I cannot seem to find an example that shows why the keyword is required over just assigning the value of a return statement. For example:
public void Function1(int input, out int output)
{
output = input * 5;
}
public int Function2(int input)
{
return input * 5;
}
...
int i;
int j;
Function1(5, out i);
j = Function2(5);
Both i and j now have the same value. Is it just the convenience of being able to initialize without the = sign or is there some other value derived that I'm not seeing? I've seen some similar answers mentioning that it shifts responsibility for initialization to the callee here. But all that extra instead of just assigning a return value and not having a void method signature?
Usually out is used for a method that returns something else, but you still need to get a different value from the method.
A good example is Int32.TryParse(input, out myVar) it will return true if it was successful and false otherwise. You can get the converted int via the out parameter.
int myOutVar;
if (Int32.TryParse("2", out myOutVar))
{
//do something with the int
}else{
//Parsing failed, show a message
}
The out / ref keywords in C# should only be used when you need to return multiple values. Even then you should first consider using a container type (such as Tuple) to return multiple values before you revert to out / ref. Whenever you're returning a single value it should just be returned.
A lot of times, using out can help by giving you a slight performance gain.
Consider the TryGetValue method on IDictionary (say myDictionary is an IDictionary<string, string>) Rather than doing this:
string value = String.Empty;
if (myDictionary.ContainsKey("foo"))
{
value = myDictionary["foo"];
}
Both ContainsKey and the indexer need to look up the key in the dictionary, but you can avoid this double-lookup on the positive case by going:
string value;
if (!myDictionary.TryGetValue("foo", out value))
{
value = String.Empty;
}
IMO, that's a decent reason for using out parameters.
Unfortunately we cannot do something like below in C#:
a,b = func(x,y,z);
something that we do in Python or other languages. out kind of overcomes that.
F# has overcome this with tuples I believe.
PS: Returning multiple values from a function might not be good always. Tiny types are good most of the times - http://www.martinfowler.com/bliki/DataClump.html
For example, Int32.TryParse returns boolean if it parsed correctly and with the out parameter changes the value. If the parsed value is 0 and it returns true it means the value you sent to parse was 0. If it returns false then the parser failed.
Some of it is for clarity. Take the TryParse() methods, like
Int32.TryParse("3", out myInt);
This returns a bool that indicates whether the string was able to be parsed into an int.
If you just had
Int32.TryParse("3", myInt);
What happens when that's called? Is myInt assigned? Does TryParse return an int?
It's not readily apparent. But if I have an out parameter, then I know that the value is getting assigned, and that the return is something else.
Basically you do something like (my database read)
if (ReadSingle<UserRecord>(cmd, out user))
Cache.Insert(cacheId, user, null,
DateTime.MaxValue, TimeSpan.FromMinutes(3));
Or else you do something like:
user = ReadSingle<UserRecord>(cmd);
if(null != user)
// Cache.Insert ...
It simplifies the code a little to use a boolean result (that a record was read from the database) and get the actual record into the variable via the out keyword.

A property or indexer may not be passed as an out or ref parameter

I'm getting the above error and unable to resolve it.
I googled a bit but can't get rid of it.
Scenario:
I have class BudgetAllocate whose property is budget which is of double type.
In my dataAccessLayer,
In one of my classes I am trying to do this:
double.TryParse(objReader[i].ToString(), out bd.Budget);
Which is throwing this error:
Property or indexer may not be passed as an out or ref parameter at
compile time.
I even tried this:
double.TryParse(objReader[i].ToString().Equals(DBNull.Value) ? "" : objReader[i].ToString(), out bd.Budget);
Everything else is working fine and references between layers are present.
Others have given you the solution, but as to why this is necessary: a property is just syntactic sugar for a method.
For example, when you declare a property called Name with a getter and setter, under the hood the compiler actually generates methods called get_Name() and set_Name(value). Then, when you read from and write to this property, the compiler translates these operations into calls to those generated methods.
When you consider this, it becomes obvious why you can't pass a property as an output parameter - you would actually be passing a reference to a method, rather than a reference to an object a variable, which is what an output parameter expects.
A similar case exists for indexers.
This is a case of a leaky abstraction. A property is actually a method, the get and set accessors for an indexer get compiled to get_Index() and set_Index methods. The compiler does a terrific job hiding that fact, it automatically translates an assignment to a property to the corresponding set_Xxx() method for example.
But this goes belly up when you pass a method parameter by reference. That requires the JIT compiler to pass a pointer to the memory location of the passed argument. Problem is, there isn't one, assigning the value of a property requires calling the setter method. The called method cannot tell the difference between a passed variable vs a passed property and can thus not know whether a method call is required.
Notable is that this actually works in VB.NET. For example:
Class Example
Public Property Prop As Integer
Public Sub Test(ByRef arg As Integer)
arg = 42
End Sub
Public Sub Run()
Test(Prop) '' No problem
End Sub
End Class
The VB.NET compiler solves this by automatically generating this code for the Run method, expressed in C#:
int temp = Prop;
Test(ref temp);
Prop = temp;
Which is the workaround you can use as well. Not quite sure why the C# team didn't use the same approach. Possibly because they didn't want to hide the potentially expensive getter and setter calls. Or the completely undiagnosable behavior you'll get when the setter has side-effects that change the property value, they'll disappear after the assignment. Classic difference between C# and VB.NET, C# is "no surprises", VB.NET is "make it work if you can".
you cannot use
double.TryParse(objReader[i].ToString(), out bd.Budget);
replace bd.Budget with some variable.
double k;
double.TryParse(objReader[i].ToString(), out k);
Possibly of interest - you could write your own:
//double.TryParse(, out bd.Budget);
bool result = TryParse(s, value => bd.Budget = value);
}
public bool TryParse(string s, Action<double> setValue)
{
double value;
var result = double.TryParse(s, out value);
if (result) setValue(value);
return result;
}
Place the out parameter into a local variable and then set the variable into bd.Budget:
double tempVar = 0.0;
if (double.TryParse(objReader[i].ToString(), out tempVar))
{
bd.Budget = tempVar;
}
Update: Straight from MSDN:
Properties are not variables and
therefore cannot be passed as out
parameters.
This is a very old post, but I'm ammending the accepted, because there is an even more convienient way of doing this which I didn't know.
It's called inline declaration and might have always been available (as in using statements) or it might have been added with C#6.0 or C#7.0 for such cases, not sure, but works like a charm anyway:
Inetad of this
double temp;
double.TryParse(objReader[i].ToString(), out temp);
bd.Budget = temp;
use this:
double.TryParse(objReader[i].ToString(), out double temp);
bd.Budget = temp;
So Budget is a property, correct?
Rather first set it to a local variable, and then set the property value to that.
double t = 0;
double.TryParse(objReader[i].ToString(), out t);
bd.Budget = t;
Usually when I'm trying to do this it's because I want to set my property or leave it at the default value. With the help of this answer and dynamic types we can easily create a string extension method to keep it one lined and simple.
public static dynamic ParseAny(this string text, Type type)
{
var converter = TypeDescriptor.GetConverter(type);
if (converter != null && converter.IsValid(text))
return converter.ConvertFromString(text);
else
return Activator.CreateInstance(type);
}
Use like so;
bd.Budget = objReader[i].ToString().ParseAny(typeof(double));
// Examples
int intTest = "1234".ParseAny(typeof(int)); // Result: 1234
double doubleTest = "12.34".ParseAny(typeof(double)); // Result: 12.34
decimal pass = "12.34".ParseAny(typeof(decimal)); // Result: 12.34
decimal fail = "abc".ParseAny(typeof(decimal)); // Result: 0
string nullStr = null;
decimal failedNull = nullStr.ParseAny(typeof(decimal)); // Result: 0
Optional
On a side note, if that's an SQLDataReader you may also make use of GetSafeString extension(s) to avoid null exceptions from the reader.
public static string GetSafeString(this SqlDataReader reader, int colIndex)
{
if (!reader.IsDBNull(colIndex))
return reader.GetString(colIndex);
return string.Empty;
}
public static string GetSafeString(this SqlDataReader reader, string colName)
{
int colIndex = reader.GetOrdinal(colName);
if (!reader.IsDBNull(colIndex))
return reader.GetString(colIndex);
return string.Empty;
}
Use like so;
bd.Budget = objReader.GetSafeString(i).ParseAny(typeof(double));
bd.Budget = objReader.GetSafeString("ColumnName").ParseAny(typeof(double));
I had the same problem (5 minutes ago) and I solved it using old style properties with getter and setter, whose use variables.
My code:
public List<int> bigField = new List<int>();
public List<int> BigField { get { return bigField; } set { bigField = value; } }
So, I just used bigField variable. I'm not the programmer, if I misunderstood the question, I'm really sorry.

which is better, using a nullable or a boolean return+out parameter

Lets say I have a function that needs to return some integer value. but it can also fail, and I need to know when it does.
Which is the better way?
public int? DoSomethingWonderful()
or
public bool DoSomethingWonderful(out int parameter)
this is probably more of a style question, but I'm still curious which option people would take.
Edit: clarification, this code talks to a black box (lets call it a cloud. no, a black box. no, wait. cloud. yes). I dont care why it failed. I would just need to know if I have a valid value or not.
I like the nullable version better, because you can use the null coalesce operator ?? on it, e.g.:
int reallyTerrible = 0;
var mightBeWonderful = DoSomethingWonderful() ?? reallyTerrible;
It depends on how you think the calling code should look like. And therefore what your function is used for.
Generally, you should avoid out arguments. On the other hand, it could be nice to have code like this:
int parameter;
if (DoSomething(out paramameter))
{
// use parameter
}
When you have a nullable int, it would look like this:
int? result = DoSomething();
if (result != null)
{
// use result
}
This is somewhat better because you don't have an out argument, but the code that decides if the function succeeded doesn't look very obvious.
Don't forget that there is another option: use Exeptions. Only do this if the case where your function fails is really an exceptional and kind of a error-case.
try
{
// normal case
int result = DoSomething()
}
catch (SomethingFailedException ex)
{
// exceptional case
}
One advantage of the exception is that you can't just ignore it. The normal case is also straight forward to implement. If the exceptional case something you could ignore, you shouldn't use exceptions.
Edit: Forgot to mention: another advantage of an Exception is that you also can provide information why the operation failed. This information is provided by the Exception type, properties of the Exception and the message text.
Why not throw an exception?
I would follow the pattern used in some place in the .Net library like:
bool int.TryParse(string s, out value)
bool Dictionary.TryGetValue(T1 key, out T2 value)
So I would say:
public bool TryDoSomethingWonderful(out int parameter)
It really depends on what you are doing.
Is null a meaningful answer? If not, I would prefer a bool TryDoSomethingWonderful(out int) method call. This matches up with the Framework.
If, however, null is a meaningful return value, returning int? makes sense.
Unless performance is the primary concern you should return an int and throw an exception on failure.
I would use the second, because I probably need to know right away if the call succeeded, and in that case I would rather write
int x;
if( DoSomethingWonderful( out x ) )
{
SomethingElse(x);
}
than
int? x = DoSomethingWonderful();
if( x.HasValue )
{
SomethingElse(x.Value);
}
I am in favor of using an output parameter. In my opinion, this is the kind of situation for which use of an output parameters is most suited.
Yes, you can use the coalesce operator to keep your code as a one-liner if and only if you have an alternative value that you can use in the rest of your code. I often find that is not the case for me, and I would prefer to execute a different code path than I would if I was successfully able to retrieve a value.
int value;
if(DoSomethingWonderful(out value))
{
// continue on your merry way
}
else
{
// oops
Log("Unable to do something wonderful");
if (DoSomethingTerrible(out value))
{
// continue on your not-so-merry way
}
else
{
GiveUp();
}
}
Additionally, if the value that I want to retrieve is actually nullable, then using a function with an output parameter and a boolean return value is, in my opinion, the easiest way to tell the difference between "I was unsuccessful in retrieving the value" and "The value I retrieved is null". Sometimes I care about that distinction, such as in the following example:
private int? _Value;
private bool _ValueCanBeUsed = false;
public int? Value
{
get { return this._Value; }
set
{
this._Value = value;
this._ValueCanBeUsed = true;
}
}
public bool DoSomethingTerrible(out int? value)
{
if (this._ValueCanBeUsed)
{
value = this._Value;
// prevent others from using this value until it has been set again
this._ValueCanBeUsed = false;
return true;
}
else
{
value = null;
return false;
}
}
In my opinion, the only reason most people tend not to use output parameters is because they find the syntax cumbersome. However, I really feel that using output parameters is the more appropriate solution to this problem, and I found that once I got used to it I found the syntax much preferable to returning a null value.
If there's only one way it can fail, or if you'll never need to know why it failed, I'd say it's probably simpler and easier to go with the nullable return value.
Conversely, if there are multiple ways it could fail, and the calling code could want to know exactly why it failed, then go with the out parameter and return an error code instead of a bool (alternatively, you could throw an exception, but based on your question, it seems you've already decided not to throw an exception).
You should rather then use a try catch. This seems like the caller does not know what might happen?
Should we check both bool and the out, or should i check both returns null and the actual return.
Let the method do what it should, and in the case where it failed, let the caller know that it failed, and the caller hanlde as requied.
Interestingly enough, my personal opinion sways significantly based on the nature of the method. Specifically, if the method's purpose is to retrieve a single value, as opposing to "doing something".
Ex:
bool GetSerialNumber(out string serialNumber)
vs
string GetSerialNumber() // returns null on failure
The second feels more "natural" to me somehow, and likewise:
bool GetDeviceId(out int id)
vs
int? GetDeviceId() // returns null on failure`
But I admit this really falls into "coding style" territory.
Oh, and I, too, would tend to favor exception throwing:
int GetDeviceId() // throws an exception on read failure
I'm still not sold on why they'd be so wrong. Can we have a thread on that, Oren? ;-)
I dislike Microsoft's "Try" pattern in which the "out" parameter is used to return a data item. Among other things, methods coded in that fashion cannot be used in covariant interfaces. I would rather see a method coded as: T GetValue(out bool Successful) or perhaps T GetValue(out GetValueErrorEnum result); or T GetValue(out GetValueErrorInfo result); if something beyond a true/false might be needed. Since every data type has a legal default value, there's no problem with deciding what to return if the function fails. Calling code can easily say:
bool success;
var myValue = Thing.GetValue(ref success);
if (success)
.. do something using myValue
else
.. ignore myValue
It would be nice if .net and C# offered true covariant 'copy out' parameters (the caller would allocate space for the result, pass a pointer to that space to the called function, and then copy the allocated space to the passed-in variable only after the function returned).

Categories

Resources