C# 7.0 introduces the ability to return references to variables rather than their values. This allows methods to return a reference to a location in memory that can be read from or written to directly, avoiding the cost of copying large value types.
This feature is particularly useful when working with large structs, arrays, or spans where copying data would be expensive. Combined with ref locals C# 7.0, you can work with references throughout your code for maximum performance.
WARNING
Using ref
can lead to unexpected side effects and code that is hard to follow and debug. It should be used sparingly when measured performance requirements and gains require that trade-off.
Code
C#
ref int FindFirst(int[] array, int value) {
for (int i = 0; i < array.Length; i++) {
if (array[i] == value)
return ref array[i];
}
throw new InvalidOperationException();
}
ref int match = ref FindFirst(numbers, 42);
match = 100; // Modifies the array directly
C#
int FindFirstIndex(int[] array, int value) {
for (int i = 0; i < array.Length; i++) {
if (array[i] == value)
return i;
}
throw new InvalidOperationException();
}
int index = FindFirstIndex(numbers, 42);
numbers[index] = 100; // Requires separate indexing
Notes
- You must use the
ref
keyword in three places: the return type, the return statement, and when calling the method - Ref locals can optionally use [
ref readonly
](/7.2/ref-readonly-method-returns C# 7.2) to prevent modification while still avoiding copies - The returned reference must have a lifetime that extends beyond the method (e.g., you cannot return
ref
to a local variable) - You can use
ref returns
with properties and indexers as well - References returned from methods can be stored in
ref local
variables or used directly in expressions