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:
- ref (C# Reference)
- out (C# Reference)
Compare
- Both the method definition and the calling method must explicitly use the
ref
/ out
keyword
- Both keywords cause parameters to be passed by reference (even value types)
- However, there is no boxing when a value type is passed by reference
- Properties cannot be passed via
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
- Must be initialized before it is passed
- Can use to pass a value to the method
out
- Does not have to be initialized before it is passed
- Calling method is required to assign a value before the method returns
- Can not use to pass a value to the method
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
- In my opinion, the concept of using the
out
keyword is similar to using the Output
enum value of ParameterDirection for declaring output parameters in ADO.NET
- Arrays in C# are passed by reference, but in order for a reassignment of the array reference to affect the reference in the calling code, the
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)