While using keyword ref
, calling code needs to initialize passed arguments, but with keyword out
we need not do so.
out
everywhere? ref
and can't use out
? The answer is given in this MSDN article . From that post:
The two parameter passing modes addressed by
out
andref
are subtly different, however they are both very common. The subtle difference between these modes leads to some very common programming errors. These include:
- not assigning a value to an
out
parameter in all control flow paths- not assigning a value to variable which is used as a
ref
parameterBecause the C# language assigns different definite assignment rules to these different parameter passing modes, these common coding errors are caught by the compiler as being incorrect C# code.
The crux of the decision to include both
ref
andout
parameter passing modes was that allowing the compiler to detect these common coding errors was worth the additional complexity of having bothref
andout
parameter passing modes in the language.
out
is a special form of ref
where the referenced memory should not be initialized before the call.
In this case the C# compiler enforces that the out
variable is assigned before the method returns and that the variable is not used before it has been assigned.
Two examples where out
doesn't work but ref
does:
void NoOp(out int value) // value must be assigned before method returns
{
}
void Increment(out int value) // value cannot be used before it has been assigned
{
value = value + 1;
}
None of these answers satisfied me, so here's my take on ref
versus out
.
My answer is a summary of the following two pages:
Compare
ref
/ out
keyword out
or ref
, because properties are really methods ref
/ out
are not considered to be part of the method signature at compile time, thus methods cannot be overloaded if the only difference between them is that one of the methods takes a ref
argument and the other takes an out
argument Contrast
ref
out
Examples
Won't compile because only difference in method signatures is ref
/ out
:
public void Add(out int i) { }
public void Add(ref int i) { }
Using ref
keyword:
public void PrintNames(List<string> names)
{
int index = 0; // initialize first (#1)
foreach(string name in names)
{
IncrementIndex(ref index);
Console.WriteLine(index.ToString() + ". " + name);
}
}
public void IncrementIndex(ref int index)
{
index++; // initial value was passed in (#2)
}
Using out
keyword:
public void PrintNames(List<string> names)
{
foreach(string name in names)
{
int index; // not initialized (#1)
GetIndex(out index);
Console.WriteLine(index.ToString() + ". " + name);
}
}
public void GetIndex(out int index)
{
index = IndexHelper.GetLatestIndex(); // needs to be assigned a value (#2 & #3)
}
Author's Random Remarks
out
keyword is similar to using the Output
enum value of ParameterDirection for declaring output parameters in ADO.NET ref
keyword must be used Example:
public void ReassignArray(ref int[] array)
{
array = new int[10]; // now the array in the calling code
// will point to this new object
}
For more info on reference types versus value types, see Passing Reference-Type Parameters (C# Programming Guide)
A contrived example of when you'd need to use ref and not out is as follows:
public void SquareThisNumber(ref int number)
{
number = number * number;
}
int number = 4;
SquareThisNumber(ref number);
Here we want number
to be an in-out variable, so we use ref
. If we had used out
, the compiler would have given an error saying we initialized an out
param before using it.
The ref keyword allows you to change the value of a parameter. The method being called can be an intermediate link in the calling chain. A method using the out keyword can only be used at the beginning of a calling chain.
Another advantage is that the existing value can be used in the logic of the method and still hold the return value.
In Oracle functions have explicit IN (default and what you get if you don't set a direction) IN/OUT and OUT parameters. The equivalent is normal (just the parameter), ref [parameter], and out [parameter].
The compiler knows that out variables shouldn't set before the call. This allows them be just declared before use. However it knows that it must be set before the function it's used in returns.
When we pass the value while calling the method prefixed by the out
keyword, it treats it entirely different like we are not passing it to the method. Instead we are actually collecting (outing) the value of the out variable from the definition section of the method to the method out variable parameter where we are calling that method.
So out variable
is the output of processing done with in the method definition, and this is the reason why we need to create it, initialize it, and modify it within the definition only.
An out
variable is used when we need return multiple values from a particular method.
While in case of a ref
variable we need to initialize it first as its memory location is transfered to method definition as parameter. Think what would happen if we are not initializing it before passing?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.