CodeOath
← All posts
C#65 min total · 17 parts

C# Fundamentals: Value Types, Reference Types, Boxing, and the Type System

Contents — Part 11 of 17: ref, out, and in Parameters
Part 11 of 17 · ~1 min

ref, out, and in Parameters

Three parameter modifiers change how an argument is passed, all working by passing a reference to the caller's storage location rather than a copy:

// ref — caller must initialize the variable first; method can read and write it
void Double(ref int x) { x *= 2; }
int a = 5;
Double(ref a);
Console.WriteLine(a); // 10

// out — caller does NOT need to initialize it first; method MUST assign it before returning
bool TryParse(string input, out int result)
{
    if (int.TryParse(input, out result)) return true;
    result = 0;
    return false;
}
if (TryParse("42", out int value)) Console.WriteLine(value); // 42

// in — like ref, but read-only inside the method; used to avoid copying a large struct
// argument without allowing the callee to mutate the caller's variable
void PrintLength(in Vector2 v) { Console.WriteLine(v.Length()); /* v.X = 1; would be a compile error */ }

out is the standard pattern for a method that needs to return more than one logical value (TryParse-style APIs throughout the .NET base class library follow this exact convention: a bool success result plus an out parameter for the actual value, avoiding an exception for the extremely common "this input might be invalid" case). in exists purely as a performance tool for large-struct parameters — it gets the "no copy" benefit of ref while still preventing the callee from mutating the caller's data, since the compiler enforces read-only access inside the method body.