ref, out, and in : Understanding Pass by Reference in C#
In C#, ref, out, and in are all keywords used for pass by reference.
Although only ref may look like it's for references, all three actually pass the memory address rather than copying values.
These keywords are mainly used for the following purposes:
- To modify a value inside a function and reflect the change outside →
ref,out - To pass large data types like structs efficiently without copying →
in
Below is a breakdown of each keyword with simple code examples.
ref
- Passes a variable declared outside the function and receives the modified value
- Therefore, the variable must be initialized before the call
- Value types are also passed by reference, avoiding copying
void AddTen(ref int number)
{
number += 10;
}
int x = 5;
AddTen(ref x);
Console.WriteLine(x); // Output: 15
out
- Used to return a new value from a function
- Therefore, the variable does not need to be initialized before the call
- The function must assign a value before returning
bool TryDivide(int a, int b, out int result)
{
if (b == 0)
{
result = 0;
return false;
}
result = a / b;
return true;
}
int value;
if (TryDivide(10, 2, out value))
Console.WriteLine(value); // Output: 5
in (C# 7.2 or later)
- Read-only reference passing
- Mainly used to reduce copy cost for large structs
- Cannot modify the value inside the function
readonly struct LargeStruct
{
public int A, B, C, D, E;
}
void Print(in LargeStruct data)
{
Console.WriteLine(data.A);
// data.A = 5; // ❌ Compile error: read-only
}
Summary
ref,out, andinall support passing by referencerefis for modifying values and reflecting them backoutis for returning resultsinis for passing large structs as read-only references- Even value types can be passed by reference to avoid copying and improve performance
Understanding when and how to use each keyword helps write clearer and more efficient code.
