Phase 5 of 30 · Topic 5.1

Pass-by-Reference: `ref`, `out`, `in` & `ref readonly` Semantics

1Concept

`ref` passes a pointer to the variable allowing read/write. `out` mandates caller assignment before return. `in` passes a reference as readonly to eliminate struct copy overhead. `ref readonly` guarantees immutability.

2Architecture Diagram

Pass-by-Value:
[ Caller Stack: Struct (128B) ] ──Copy 128 Bytes──> [ Callee Stack: Copy (128B) ]

Pass-by-Reference (`in` / `ref readonly`):
[ Caller Stack: Struct (128B) ] <──8-Byte Pointer── [ Callee: Direct Access (0B Copy) ]

3Code Example

C# 13 & .NET 9
using System;

public struct LargeMatrix128Bytes
{
    public long M1, M2, M3, M4, M5, M6, M7, M8;
}

public class RefSemanticsDemo
{
    // Zero-copy readonly parameter
    public static long ComputeSum(in LargeMatrix128Bytes matrix)
    {
        // matrix.M1 = 99; // COMPILE ERROR: Readonly variable
        return matrix.M1 + matrix.M2;
    }

    public static void Main()
    {
        var mat = new LargeMatrix128Bytes { M1 = 100, M2 = 200 };
        long sum = ComputeSum(in mat);
        Console.WriteLine($"Computed Sum without struct copy: {sum}");
    }
}

4Expected Output

Computed Sum without struct copy: 300

5Key Takeaways

  • Use `in` for structs > 16 bytes to eliminate defensive stack copying.
  • `out` parameters are ideal for TryParse patterns returning status and payload.
  • `ref readonly` returns protect internal arrays/buffers while giving direct pointer performance.