SyntaxStudy
Sign Up
C# Out, Ref, and In Parameters
C# Beginner 1 min read

Out, Ref, and In Parameters

`out` parameters allow a method to return multiple values without using a tuple or creating a wrapper type. The caller declares a variable (or uses an inline declaration) and passes it with the `out` keyword; the method must assign a value to every `out` parameter before returning. `ref` parameters pass a variable by reference in both directions — the method can both read and write the caller's variable. `in` parameters are read-only references: the method can read the value but the compiler prevents it from writing to it. `in` is mainly used for large structs to avoid copying without allowing mutation. The `TryXxx` pattern (e.g. `int.TryParse`, `Dictionary.TryGetValue`) is idiomatic C#. It returns a bool indicating success and delivers the result through an `out` parameter, avoiding exceptions for predictable failure cases like invalid user input.
Example
// out, ref, and in parameters

// out parameter — inline variable declaration (C# 7+)
if (int.TryParse("42", out int parsed))
    Console.WriteLine($"Parsed: {parsed}");

// Custom method with multiple out parameters
static bool TryDivide(int numerator, int denominator,
                       out int quotient, out int remainder)
{
    if (denominator == 0)
    {
        quotient  = 0;
        remainder = 0;
        return false;
    }
    quotient  = numerator / denominator;
    remainder = numerator % denominator;
    return true;
}

if (TryDivide(17, 5, out int q, out int r))
    Console.WriteLine($"17 / 5 = {q} remainder {r}"); // 3 remainder 2

// ref parameter — bidirectional
static void Increment(ref int value, int by = 1) => value += by;

int counter = 10;
Increment(ref counter);
Increment(ref counter, by: 5);
Console.WriteLine(counter); // 16

// Swap using ref
static void Swap<T>(ref T a, ref T b) => (a, b) = (b, a);

string x = "hello", y = "world";
Swap(ref x, ref y);
Console.WriteLine($"{x} {y}"); // world hello

// in parameter — read-only reference (efficient for large structs)
static double MagnitudeSquared(in System.Numerics.Vector3 v) =>
    v.X * v.X + v.Y * v.Y + v.Z * v.Z;

var vec = new System.Numerics.Vector3(1, 2, 3);
Console.WriteLine(MagnitudeSquared(in vec)); // 14