Difference between 'ref' and 'out' keywords in C#

Some keywords that should't be confused...

Both keywords allow the caller of a method to send a reference of a variable, however both have subtle differences that you better take in consideration. These differences have both technical and funcional meaning.

C# works with 'pass by value'. This means that the conntent of each variable is copied when you send it to a method. Inside of that method, the content could be modified but this won't impact the original value of the variable outside of that method call. Here is an example:

public void MethodOne()
{
    int x = 10;

    Console.WriteLine("methodOne: " + x);

    this.MethodTwo(x);

    Console.WriteLine("methodOne: " + x);
}

public void MethodTwo(int x)
{
    Console.WriteLine("methodTwo: " + x);
    // Assignment to the x variable (not the same as in methodOne)
    x = x + 10;
    Console.WriteLine("methodTwo: " + x);
}
  • MethodOne is declaring a local variable X and assigns a value of 10. When we call MethodTwo, the system will create a NEW VARIABLE X of type int and will assign in it A COPY OF THE VALUE as it is in that point of time in MethodOne.
  • In MethodTwo is using that X value to do some calculations and assign it to the same X variable.
  • Since MethodTwo's X variable is not the same 'variable' as MethodOne's X variable. The modifications done to MethodTwo's X won't affect MethodOne's X.

The output of the previous example is:

methodOne: 10
methodTwo: 10
methodTwo: 20
methodOne: 10

The ref and out keywords

ref and out will work pretty much in the same way. They will help us SEND A REFERENCE to the variable NOT A COPY OF THE VALUE. Let's start with ref.

ref keyword

ref keyword will be used in the case where you want to send an input variable to a method. You have to declare it in the list of parameters both when you declare the method and when you call it.  Here is an example (I have highlighted the lines where the ref keyword is used):

public void MethodOne()
{
    int x = 10;

    Console.WriteLine("methodOne: " + x);

    this.MethodTwo(ref x);

    Console.WriteLine("methodOne: " + x);
}

public void MethodTwo(ref int x)
{
    Console.WriteLine("methodTwo: " + x);
    // Assignment to the x variable (not the same as in methodOne)
    x = x + 10;
    Console.WriteLine("methodTwo: " + x);
}

And here is the output:

methodOne: 10
methodTwo: 10
methodTwo: 20
methodOne: 20

Important!

  • In the case of the ref keyword, the variable has to be initialized (contain a value) before being send to MethodTwo.
  • The analogy in this case is: MethodTwo, you will need X to perform your job so here it is with a value. However, if you need to modify that value please be free to do so and I will be able to see the changes afterwards.
  • If you do not initialize the value of x in MethodOne before sending it as a ref to MethodTwo, the compiler will raise an error saying: Local variable 'x' might not be initialized before accessing.

out keyword

The out keyword in exchange works very similarly to the ref keyword in the sense that both send references, not the values.

public void methodOne()
{
    int x;

    bool success = MethodTwo(userInput, out x);

    if (wasParsed)
    {
        Console.WriteLine(x);
    }
}

public static bool MethodTwo(out Int32 result)
{
    result = 10;
    return true || false;
}

Important!

  • In the case of the out keyword, it is not mandatory to initialize the variable to be send to MethodTwo.
  • The analogy in this case is: MethodTwo, I need you to process something for me and the result of that calculation please set it in this variable I am sending to you.
  • If you do not initialize the value of x in MethodTwo before returning it, the compiler will raise an error saying: Local variable 'x' might not be initialized before accessing.