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)