Why use out keyword instead of assignment in c#? - 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.

Related

I can't add to a value when i use parameter, but it works fine when not in the function

So when i try to += 1 in the function, the value doesent update, But i can update the value without paramter just fine.
Please help.
public void buystock(int amountofstocks, int stockvalue)
{
int stocksbuy = 400;
if (amountofstocks >= 40)
{
if (GetComponent<Money>().MoneyValue >= (stockvalue + stocksbuy))
{
GetComponent<Money>().MoneyValue -= stockvalue + 400;
amountofstocks += 1;
}
}
else
{
if (GetComponent<Money>().MoneyValue >= (stockvalue + 10))
{
GetComponent<Money>().MoneyValue -= stockvalue + 10;
}
}
}
and my other one which is:
public void buyoil1()
{
buystock(oil1amountofstocks, oil1value);
}
Thanks a lot!
Int is value type, so it's value is copied (opposite to it's reference) into function parameter and any modification on that parameter is local.
In order to pass reference of int, you should use ref keyword.
Try following
public void buystock(ref int amountofstocks,ref int stockvalue)
You are passing a struct to your method which is copying the value rather than passing a reference to the variable.
Consider using a return value, out or ref to achieve the desired result.
Here is the official documentation on passing arguments to methods in C# which helps explain the problem
Its amazing how many answers here are simply wrong. They all go on about int being a value type and that bit of information is completely irrelevant here.
int is an immutable type, you can’t mutate it which would be the only reason why value types could be relevant in the context of this question.
Somehow the answers seem to be mixing up amountofstocks =+ 1 with mutating a value type which is simply false! The only thing that is going on here is that the variable amountofstock is being assigned a new value and because the parameter is passed by value (default behavior in c#) the assignment has no effect whatsoever back at the call site (the assignment is made on a copy).
The exact same thing would happen if amountofstock were a reference type. If amountofstring were to be a string there would be no change at all in the behavior of your code.
To make a long story short, the behavior you are seeing is due to the fact that parameters in c# are, by default, passed by value, period. It has nothing to do, in this particular case, with amountofstock being a value type.
If you need to reassign the value of a parameter and have it persist back at the call site then you need to pass it by reference; in your case ref amountofstock although in some scenarios out is more appropriate.

Using out keyword in c#

can anyone suggest me the exact use of out keyword as a paramter, and how its connected for returning multiple values from the function, as in this POST, i am confused with out variable with normal variable. can anyone help me for this.
This is frequently confusing, and I think the MSDN documentation actually is a bit "clear only if already known". That is, it is correct, but it really only makes sense if you already understand the concept.
Here's how I think of it.
A regular parameter makes a copy of the value of the argument. When you say:
static int M(int z) { z = z + 1; return z; }
...
int x = 123;
int y = M(x);
That is just like you said:
int x = 123;
int z = x; // make a copy of x
z = z + 1;
int y = z;
A ref or out parameter make an alias for an existing variable. When you say
static void N(ref int q) { q = q + 1; }
...
int x = 123;
N(x);
That is the same as saying:
int x = 123;
// MAGIC: q is now an another name for variable x
q = q + 1;
q and x are two different names that refer to the same variable. Incrementing q also increments x because they are the same. z and x in the previous example are two different names that refer to two different variables. Incrementing z does not change x.
Summing up: "out" and "ref" just mean "do not make a new variable; rather, temporarily make a second name for an existing variable".
Is that now clear?
UPDATE: I did not say what the difference between "out" and "ref" is. The difference is simple. On the "caller" side, a "ref" must be a definitely assigned variable before the method is called. An "out" need not be. On the "callee" side, a "ref" may be read before it is written to, but an "out" must be written to before it is read. Also, an "out" must be written to before control leaves the method normally.
MSDN documentation already does a great job explaining this:
The out keyword causes arguments to be passed by reference. This is
similar to the ref keyword, except that ref requires that the variable
be initialized before being passed. To use an out parameter, both the
method definition and the calling method must explicitly use the out
keyword. For example:
class OutExample
{
static void Method(out int i)
{
i = 44;
}
static void Main()
{
int value;
Method(out value);
// value is now 44
}
}
It's very frequently used in a pattern that "tries" to get a value, something like:
int result;
if(Int32.TryParse("123", out result))
{
Console.WriteLine(result + 1);
}
out keyword should be used when you want to:
a) Allow your function to modify specific variable from calling code stack AND
b) enforce setting this variable value inside your function
MSDN is always a good place to start
In most languages c# included you can pass values in 2 ways, by value, by reference.
by value gives the method a copy of your data, so changing the data wont have any effect on the original data
by reference essentially gives the method the memory address of your data, so if the method modifies the data, it changes the original.
Out is a special type of ref, in that you do not need to initialise the variable before you call the method, it can be called with null being passed in. and it MUST be set by the method.
Another way you can think of it (from the outside code's point of view) is:
val = read only
ref = read/write
out = write only.
http://msdn.microsoft.com/en-us/library/t3c3bfhx(v=vs.80).aspx
out keyword is good if you want to return multiple values of pre-defined types (for example an int, a List<string> and a DateTime), and you don't want to create a new class just for this purpose.
Ok,
let look at the usual pattern for this kind of function - the TrySomething.
Suppose you have a function that might succeed giving you an value or not but you don't won't to use an exception for this because you don't want the overhead or it's a common trait.
Then you normaly return true if the method suceeded and false if not. But where would you put your outputvalue to?
One possible answer is using an out parameter like this:
bool TrySomething(MyInputType input, out MyOutputType output)
{
output = default(MyOutputType);
/* ... Try getting the answer ... */
if (!successful)
return false;
output = successfulOutput;
return true;
}
Remark:
Or you might consider using a Tuple<bool,MyOutputType> and indeed F# interpretes the pattern above as resulting in such a tuple by itself.

C# data validation using Parse() for any T that has Parse implementation

I am simplifying my code (I like to write the least amount of lines per function performed) and I often come across the lengthy process of data validation. So decided to write a Validate function, in pseudocode:
public static bool Validate(string input, out object output){
// try to parse data
try {
(TypeOf(object)) output = new (TypeOf(object));
output = (TypeOf(object)).Parse(input);
return true;
} catch {
return false;
}
}
So if I use in my code to validate several text boxes, it looks nice and very readable:
double var1;
Int32 var2;
byte var3;
if (!Validate(txtDouble.text, var1)) return "Error validating a Double";
if (!Validate(txtInt32.text, var2)) return "Error validating a Int32";
if (!Validate(txtByte.text, var3)) return "Error validating a byte";
// else all data is valid, continue
Process(var1, var2, var3)
I could create a static class Validate and overload for each type, but since I am planning on using on types that include the Parse method, it seems to me that there should be a way of implementing the above function... I just don't know what I am looking for. An interface keeps coming to my mind, but failing at implementing.
Thanks!
The framework providers already wrote your function for you, it's called TryParse. There is no generic nature to it, but it's called the exact same way you're calling Validate. Might as well use what's already there.
double var1;
if (!double.TryParse(input, out var1)) return "Invalid input";
The method is available for your double, int, float, char, DateTime, etc.
You're better off creating a static class with overloads (that call TryParse instead of Parse for the various types involved. The list is fairly short and your only other options will be convoluted.
Or you could just call the appropriate version of TryParse directly in your code. If you aren't inserting any additional validation (hence the need for your own validation class), then it won't be any more verbose than your pseudocode.
You could use something like this (it uses reflection):
private static void Test()
{
var r1 = TryParse("23", typeof(int));
var r2 = TryParse("true", typeof(bool));
}
private static bool TryParse(string valueToParse, Type type)
{
//there are more then one TryParse method and we need the one with 2 parameters
var method = type.GetMethods().Where(m => m.Name == "TryParse" && m.GetParameters().Count() == 2).Single();
var instance = Activator.CreateInstance(type); //create instance of the type
var result = method.Invoke(null, new object[] { valueToParse, instance });
return (bool)result;
}
but it's really fancy code (maybe there is a chance to write it a bit better;) ) and I would never use it.
As Anthony Pegram suggested you should create few overloads methods with TryParse - it's much cleaner and better solution.

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