Question

C# ref vs out: What’s the Difference and When Should You Use Each?

csharpreferencekeyword

Question

In C#, I am creating a method where I want to pass an object so the method can modify it. What is the difference between these two method signatures?

public void MyFunction(ref MyClass someClass)

and

public void MyFunction(out MyClass someClass)

Which one should I use, and why?

Short Answer

By the end of this page, you will understand how ref and out work in C#, how they differ, and when each should be used. You will also see how they affect method calls, variable assignment, and code clarity in real programs.

Concept

In C#, method arguments are normally passed by value. That means the method receives its own copy of the variable.

When you use ref or out, you are telling C# to pass the variable by reference instead. That means the method can work with the caller's original variable, not just a copy.

This matters because there are two different needs:

  • ref means the variable already has a value before the method is called, and the method may read or change it.
  • out means the variable does not need a value before the call, but the method must assign one before returning.

Key difference

  • ref: input and possibly output
  • out: output only

Why this matters

Choosing between them communicates intent:

  • Use ref when the method needs the current value and may update it.
  • Use out when the method's job is to produce a value for the caller.

This helps other developers understand your code and lets the compiler enforce the right rules.

Important note about objects

MyClass is a reference type, but that does not mean ref and out are unnecessary.

If you pass an object normally, the method can modify the object's internal state:

public void UpdateName(MyClass person)
{
    person.Name = "Alice";
}

But if you want the method to replace the caller's variable with a different object instance, then you need ref or out:

public void ReplaceObject(ref MyClass person)
{
    person = new MyClass();
}

So the real question is often:

  • Do you want to modify the object's properties? Normal parameter may be enough.
  • Do you want to reassign the caller's variable itself? Use ref or out.

Mental Model

Think of a variable as a labeled sticky note.

  • With a normal parameter, the method gets a copy of the sticky note.
  • With ref, the method gets access to the original sticky note. It can read what is currently written there and change it.
  • With out, the method gets the original sticky note too, but it should treat it like an empty note that must be filled in before leaving.

Another way to think about it:

  • ref = "Here is a value I already have; you may update it."
  • out = "Please give me a value back through this variable."
Take Quiz

Syntax and Examples

Basic syntax

public void UseRef(ref int number)
{
    number = number + 1;
}

public void UseOut(out int number)
{
    number = 10;
}

The caller must also use the same keyword:

int a = 5;
UseRef(ref a);

int b;
UseOut(out b);

Example with a class

public class MyClass
{
    public string Name { get; set; }
}

Using ref

public void ResetPerson(ref MyClass person)
{
    person = new MyClass { Name = "New Person" };
}

MyClass p = new MyClass { Name = "Old Person" };
ResetPerson(ref p);
Console.WriteLine(p.Name); // New Person

Here, the caller already has a value in p, and the method replaces it.

Using out

public void CreatePerson(out MyClass person)
{
    person = new MyClass { Name = "Created Person" };
}

MyClass p;
CreatePerson(out p);
Console.WriteLine(p.Name); // Created Person

Here, p does not need a value before the call. The method is responsible for assigning it.

Modifying an object without ref or out

public void RenamePerson(MyClass person)
{
    person.Name = "Updated Name";
}

MyClass p = new MyClass { Name = "Original" };
RenamePerson(p);
Console.WriteLine(p.Name); // Updated Name

This works because the method received a copy of the reference, and both variables still point to the same object.

But this does not replace the caller's variable:

public void TryReplace(MyClass person)
{
    person = new MyClass { Name = "Different" };
}

MyClass p = new MyClass { Name = "Original" };
TryReplace(p);
Console.WriteLine(p.Name); // Original

The reassignment only affects the local parameter variable inside the method.

Step by Step Execution

Consider this example:

public static void BuildMessage(out string message)
{
    message = "Hello";
    message += " World";
}

string result;
BuildMessage(out result);
Console.WriteLine(result);

Step by step

  1. string result;

    • A variable named result is declared.
    • It does not yet have a value.
  2. BuildMessage(out result);

    • The method receives access to the caller's actual variable.
    • Because it is out, the method must assign message before returning.
  3. Inside the method: message = "Hello";

    • The caller's result variable now has the value "Hello".
  4. message += " World";

    • The value becomes "Hello World".
  5. The method returns.

    • result in the caller now contains "Hello World".
  6. Console.WriteLine(result);

    • Output: Hello World

Compare with ref

public static void AddSuffix(ref string text)
{
    text += "!";
}

string value = "Hi";
AddSuffix(ref value);
Console.WriteLine(value);

Step by step:

  1. value starts as "Hi".
  2. The method receives the original variable by reference.
  3. The method reads the current value.
  4. It appends "!".
  5. After the method returns, value is "Hi!".

This shows the main difference:

  • out starts with assignment responsibility inside the method.
  • ref starts with an existing value from the caller.

Real World Use Cases

When ref is used

ref is useful when a method needs an existing value and may update it.

Examples:

  • Updating a running total
  • Swapping two variables
  • Modifying a struct efficiently
  • Passing configuration or state that may be changed

Example:

public static void Increment(ref int count)
{
    count++;
}

When out is used

out is commonly used when a method tries to produce a result in addition to returning success or failure.

Examples:

  • Parsing text into another type
  • Returning a computed value from a lookup
  • Returning multiple results from one method

Example:

if (int.TryParse("123", out int number))
{
    Console.WriteLine(number);
}

This is a classic out pattern:

  • The method returns true or false
  • The parsed value comes back through the out parameter

For your specific situation

If your method only needs to change properties on the object, you usually do not need either ref or out.

If your method needs to assign a brand new object to the caller's variable:

  • use ref if the caller already has a meaningful object/value
  • use out if the method is responsible for creating and returning one
Take Quiz

Real Codebase Usage

In real codebases, ref and out are used less often than beginners expect.

Common pattern: no ref needed for object mutation

Developers often write methods like this:

public void ApplyDiscount(Order order)
{
    order.Total = order.Total * 0.9m;
}

Because Order is a reference type, its properties can be updated without ref.

Common pattern: out for Try-methods

A very common convention in .NET is the Try... pattern:

public bool TryGetUser(string id, out User user)
{
    user = repository.Find(id);
    return user != null;
}

This is used for:

  • parsing
  • dictionary lookups
  • cache retrieval
  • validation with result output

Common pattern: early return with out

public bool TryCreateEmail(string input, out string email)
{
    if (string.IsNullOrWhiteSpace(input))
    {
        email = string.Empty;
        return false;
    }

    email = input.Trim().ToLower();
    return true;
}

Notice that every path assigns email. The compiler requires that for out.

Guarded updates with ref

ref is more likely when working with value types or when a variable truly needs to be replaced.

public void NormalizeScore(ref int score)
{
    if (score < 0)
    {
        score = 0;
        return;
    }

    if (score > 100)
    {
        score = 100;
    }
}

API design tip

If a method feels awkward with many out parameters, it is often better to return a custom object instead. That usually improves readability.

Common Mistakes

1. Using ref when plain object mutation is enough

Broken thinking:

public void ChangeName(ref MyClass person)
{
    person.Name = "Alice";
}

This works, but ref is unnecessary if you are only changing properties.

Better:

public void ChangeName(MyClass person)
{
    person.Name = "Alice";
}

2. Forgetting to initialize a ref variable before calling

Broken code:

int x;
UseRef(ref x); // Error

Why it fails:

  • ref requires the variable to already be assigned.

Correct:

int x = 0;
UseRef(ref x);

3. Forgetting to assign an out parameter in all code paths

Broken code:

public bool TryGetValue(bool ok, out int result)
{
    if (ok)
    {
        result = 1;
        return true;
    }

    return false; // Error: result was not assigned
}

Correct:

public bool TryGetValue(bool ok, out int result)
{
    if (ok)
    {
        result = 1;
        return true;
    }

    result = 0;
    return false;
}

4. Thinking out means "optional"

out does not mean the method may skip assignment. It means the opposite: assignment is required.

5. Forgetting the keyword at the call site

Broken code:

int x = 5;
UseRef(x); // Error

Correct:

int x = 5;
UseRef(ref x);

6. Replacing an object without ref

Broken expectation:

public void Replace(MyClass item)
{
    item = new MyClass();
}

This does not replace the caller's variable.

Use ref or out if you need that behavior.

Comparisons

FeaturerefoutNormal parameter
Passed by referenceYesYesNo
Must be assigned before method callYesNoYes
Must be assigned inside methodNoYesNo
Method can read existing value immediatelyYesNo, not safely before assignmentYes
Good for input and outputYesNo, mainly outputNo
Good for returning a produced valueSometimesYesNo

ref vs out

  • Use ref when the incoming value matters.
  • Use out when the method is supposed to create or supply the value.

out vs return value

OptionBest when
Return valueThe method produces one main result
out parameterThe method returns success/failure and also needs to provide a value
Custom objectThe method needs to return several related values clearly

For reference types specifically

GoalNeed ref/out?
Change object propertiesUsually no
Replace the object variable itselfYes
Create a new object for callerout often fits
Update an existing object variable based on its current valueref often fits
Take Quiz

Cheat Sheet

Quick rules

  • ref = variable must already have a value before the call
  • out = variable does not need a value before the call
  • out parameter must be assigned inside the method before it returns
  • Both ref and out must appear in:
    • the method declaration
    • the method call

Syntax

void Update(ref int x)
{
    x = x + 1;
}

void Create(out int x)
{
    x = 10;
}

Calling

int a = 5;
Update(ref a);

int b;
Create(out b);

Object rule

For classes:

void Change(MyClass obj)
{
    obj.Name = "Updated"; // no ref needed
}

But to replace the variable itself:

void Replace(ref MyClass obj)
{
    obj = new MyClass();
}

Choose this

  • Use normal parameter if only changing object contents
  • Use ref if the method needs the current variable value and may replace/update it
  • Use out if the method's job is to produce a value for the caller

Common edge case

This does not replace the caller's object:

void Wrong(MyClass obj)
{
    obj = new MyClass();
}

Because only the local copy of the reference changes.

FAQ

Do I need ref to modify a class object in C#?

No. If you only want to change the object's properties or fields, you can pass the object normally.

When should I use out instead of ref?

Use out when the method is meant to assign and return a value through the parameter, especially in Try... methods.

Can ref and out both change the caller's variable?

Yes. Both pass the variable by reference, so both can change the caller's variable.

Why must an out parameter be assigned inside the method?

Because out means the method is responsible for producing that value. The compiler enforces this rule.

Is out only for primitive types?

No. It can be used with classes, structs, and other types.

If I want to replace an object with a new instance, should I use ref or out?

Use ref if the caller already has a meaningful value and the method may update or replace it. Use out if the method is supposed to provide the object from scratch.

Why do many C# methods avoid ref and out?

Because they can make APIs harder to read. Often a return value or a small result object is clearer.

Take Quiz

Mini Project

Description

Build a small C# console example that demonstrates all three cases: modifying an object's property with a normal parameter, replacing an object with ref, and creating an object with out. This helps you see exactly when ref and out are necessary and when they are not.

Goal

Create a program that shows the difference between normal parameters, ref, and out using a simple Person class.

Requirements

  • Create a Person class with a Name property.
  • Write one method that changes Name without using ref or out.
  • Write one method that replaces a Person object using ref.
  • Write one method that creates a new Person using out.
  • Print results before and after each method call to compare behavior.
Take Quiz

Keep learning

Related questions

View more