A ref local or ref parameter is an alias to another variable. Before C# 7.3 that alias was fixed at the point of declaration, so there was no way to make a ref point somewhere else afterwards. Code that wanted to walk across a set of aliases had to use indexers, unsafe pointers, or duplicate the whole method body for each target.
C# 7.3 allows a ref to be reassigned with = ref.
Code
csharp
ref int Pick(int[] values, bool highest)
{
ref int chosen = ref values[0];
if (highest)
chosen = ref values[values.Length - 1]; // point at the last element
return ref chosen;
}
int[] data = { 3, 1, 4, 1, 5 };
ref int slot = ref Pick(data, true);
slot = 99;
// data is now 3, 1, 4, 1, 99csharp
ref int Pick(int[] values, bool highest)
{
if (highest)
return ref values[values.Length - 1];
return ref values[0];
}Notes
- The syntax is
target = ref source- therefgoes on the right-hand side, which distinguishes it from an ordinary assignment - The containing method must be a
ref-returning context or the local must already be declared withref - Reassignment does not copy the value; it rebinds the alias, so writes afterwards affect the new target
- The reassigned ref must not outlive the storage it points at - the compiler enforces the same escape rules as ref locals C# 7.0
- A
reffield cannot be reassigned after construction, because the escape rules cannot prove the new target outlives the struct; this feature applies to locals and parameters