C# When to use Ref vs Out

Interesting question asked of me today by another developer who was fairly new to C# and that was

What’s the difference between ref and out?

Well it’s a good question and it took me a minute or two to remember but once I had remembered (and supplemented my knowledge thanks to a bit of Googling) I thought I’d add the answer here.

They’re both passed by reference

This is the first point to note but…

Ref Parameters Need to be Initialised (or Initialized if you’re American)

What this means is that any method you declare which accepts a parameter prefixed with ref needs to have a value assigned to it before it can be passed to the method. Take the following code example.  If I were to replace int x = 1; with int x; then I’d get the build error “Use of unassigned local variable ‘x'”. Note that int y doesn’t need to be initialised:

class RefVsOut
{
   static void Main(string[] args)
   {
      int x = 1;
      int y;
      RefAndOut(ref x, out y);
      // Will output x: 11 and y: 5
      Console.WriteLine("x: " + x.ToString() + "; y: " + y.ToString());
      Console.ReadKey();
   }

   static void RefAndOut(ref int x, out int y)
   {
      y = 5;
      x += 10;
   }
}

Out parameters are just that

True.  They’re just for passing data out of a method.  In the example above if I change the code so that I initialise the y variable e.g. int y = 5; then change the line y = 5; to y += 5; I’ll get the build error “Use of unassigned out parameter ‘y’“.  This is purely down to the change y += 5 that I made and is because the only thing that can (and has to) happen to the y parameter in the RefAndOut method is for a value to be assigned to it before the method returns.

You cannot overload with just ref and out

This is an important point to note.  If you’re looking to overload your methods you cannot have methods that just differ with ref and out parameters but you can overload if one takes an out or ref and the other doesn’t e.g.

class RefVsOut
{
   // You'll get a compilation error if you try this
   public void MethodOne(ref int x) {...}
   public void MethodOne(out int x) {...}

   // This'll work though
   public void MethodTwo(int x) {...}
   public void MethodTwo(ref int x) {...}

   // And so will this
   public void MethodThree(int x) {...}
   public void MethodThree(out int x) {...}
}

For additional information you can also visit this MSDN article at: http://pu.gl/36