All languages, or at least most, have some way of passing a value by reference. When we wish to return more than one values from a method or simply if we want to use the classic value swap paradigm then we need to pass values by reference to our method. C has pointers (which in fact you are still passing the pointer to your method by value, but in fact that pointer has a reference to the variable you want to change) Visual basic has the ByRef argument and many other languages have their own way of doing this.
C# on the other hand has two keywords. Out and Ref. the syntax is similar it looks something like.
T methodName( out T value1, ref T value2);
In both cases any change that happens to value1 and value2 inside the method methodName will propagate to the main program.
So what is their difference between the two?
First let’s start by explaining that this difference is enforced by the C# compiler and not by the CLR. Which means that out and ref compile to the same bytecode in the end. Why the difference then?
Well the differences in fact are syntactical sugar for software engineers and ease communication with each other.
This also means something else. This means that you cannot overload a method which their main difference is that one is using ref and the other one is using out. E.g. The following example
bool myFunc(ref int smth); bool myFunc(out int smth);
Will not compile as it will end up being the same method signature in bytecode.
So let’s dive in and see what’s what.
When we are using the out keyword we are simply telling to the method caller that in this variable a value will be returned. A good example is the tryparse method
public static bool TryParse( string s, out int result)
The TryParse method belongs in the Int32 class as a static method. It needs to return more than one values and so it uses the out keyword. It returns true or false if the parsing to Int32 succeeded and the result is stored in the out int result variable. Just like any other language we know that uses pass by reference.
So result is in fact an output variable used for returning more than one output. Hence the name out.
Now ref variables in fact mean pass by reference. So why use something different? Well ref variables are meant to firstly return an extra result but also means that this variable will be used in calculations as well. in the TryParse example the result variable will never be used in the context of the method. It will only be used to return a result. Nothing more. The value does not need to be initialized nor have any value in it.
Now let’s think of a method that simply takes an int, does some calculations with it and returns it. While also returning if the limit has been reached (if we have an overflow). How would you do that? As we explained out is in fact syntactical sugar for pass by reference and store a value. As we said it does not have to be initialized with any value nor that value will be used. So this is the proper usage of ref.
The following method
bool myFunc(ref int smth);
Is telling the developer that will use that method that in fact the contents of smth will be used in the calculations that will be performed inside the body of MyFunc.
So this is the basic difference between the two. Simple syntactical sugar to aid developers in understanding what the usage is of the method we have created.