How to Use Ref and Out Parameters in C

In C#, arguments are typically passed to methods by value, meaning the method receives a copy of the data. The ref and out keywords allow you to pass arguments by reference instead, enabling methods to modify the original variable stored in the caller's memory. This article explains the mechanics of both keywords, highlights their core differences, and demonstrates how to implement them effectively in your code.

The ref Keyword

The ref keyword indicates that an argument is passed by reference. When using ref, the variable must be initialized before it is passed to the method. Inside the method, reading the value is allowed, and any modifications will directly affect the caller's original variable.

Syntax and Example

Both the method definition and the calling code must explicitly use the ref keyword.

public class RefExample
{
    public static void Increment(ref int number)
    {
        // Reading the value is allowed
        number += 1; // Modifying affects the caller's variable
    }

    public static void Main()
    {
        int count = 10; // Must be initialized before passing
        Increment(ref count);
        Console.WriteLine(count); // Outputs: 11
    }
}

Use ref when a method needs to inspect and modify an existing value provided by the caller.

The out Keyword

The out keyword also passes arguments by reference, but it is primarily used to return data from a method. Unlike ref, a variable passed as out does not need to be initialized before being passed. However, the called method is strictly required to assign a value to the out parameter before it exits.

Syntax and Example

Like ref, both the definition and invocation must include the out keyword. C# also supports inline declaration of out variables.

public class OutExample
{
    public static bool TryDivide(int dividend, int divisor, out int result)
    {
        if (divisor == 0)
        {
            result = 0; // Must be assigned before returning
            return false;
        }

        result = dividend / divisor;
        return true;
    }

    public static void Main()
    {
        // Inline variable declaration is supported
        if (TryDivide(10, 2, out int outcome))
        {
            Console.WriteLine($"Result: {outcome}"); // Outputs: Result: 5
        }
    }
}

A common real-world application of out is the standard .NET TryParse pattern (e.g., int.TryParse).

Key Differences Between ref and out

Feature ref out
Caller Initialization Required before calling the method. Not required before calling the method.
Callee Assignment Optional. The method may leave it untouched. Mandatory. The method must assign a value before returning.
Primary Purpose Modifying an existing value in place. Returning multiple values from a method.
Direction Two-way (in and out). One-way (out only).

Summary of Best Practices

  • Use ref when a method must operate on and update an existing state.
  • Use out when you want a method to return multiple values or status-plus-result pairs.
  • In modern C# (C# 7.0+), consider using tuples ((bool success, int result)) as a cleaner, more readable alternative to out parameters when returning multiple values.