This is among one of the most important questions asked in C# interviews. It is very well known that both ref and out parameters are used to pass an argument within a method.
But the question here is, what are the scenarios we need them and which one should we prefer.
We always heard that in C# there are two types of “types”:
- Value types contain the data itself.
- Reference types have their value as a reference to the data, instead of the data itself.
We are pretty much aware of the value type. So the main concern here is for reference type. In case of the reference type we can use either out or ref keyword.
Reference parameters actually never pass the value of a variable in the invoked method, instead they use the variable themselves.
From the point of storage, instead of allocating a new storage for that variable in the method declaration, the same storage space is used, so in this case the value of the variable in the member method and the value of the reference parameter will always remain the same.
Output parameters specified at the time of calling doesn't need to have been assigned a value before it is passed to the invoked method. When the method is invoked completely we can read that variable as it is assigned by now.
Following the same pattern as reference parameters, output parameters also do not create a new storage location, but use the storage location of the variable specified on the invocation. Output parameters need the out modifier as part of both the declaration and the invocation. That means it's always clear when you're passing something as an output parameter.
Note: Reference parameters require ref modifier and Output parameters need the out modifier as part of both the invoking and invoked method.
- int x;
- Foo(out x); // OK
- int x;
- Foo(ref x); // ERROR
Which one to choose
ref parameters are for data that might be modified, out parameters are for data that's an additional output for the function (for example int.TryParse) that are already using the return value for something.
We should use out unless we need ref.
It makes a big difference when the data needs to be marshalled, for example to another process that can be costly. So you want to avoid marshalling the initial value when the method doesn't make use of it.
Beyond that, it also shows the reader of the declaration or the call whether the initial value is relevant (and potentially preserved), or thrown away.
As a minor difference, an out parameter need not be initialized.
The following is an example of out:
- string a, b;
- person.GetBothNames(out a, out b);
Where GetBothNames is a method to retrieve two values atomically, the method won't change the behaviour of whatever a and b are. If the call goes to a server in Hawaii, copying the initial values from here to Hawaii is a waste of bandwidth.
- string a = String.Empty, b = String.Empty;
- person.GetBothNames(ref a, ref b);
That however could confuse readers, because it looks like the initial values of a and b are relevant (though the method name would indicate they are not).
The following is an example for ref:
- string name = textbox.Text;
- bool didModify = validator.SuggestValidName(ref name);
Here the initial value is relevant to the method.
From the compiler's point of view
ref tells the compiler that the object is initialized before entering the function, whereas out tells the compiler that the object will be initialized inside the function.
So whereas ref is two-ways, out is out-only.
Both ref and out cannot be used in method overloading simultaneously. However, ref and out are treated differently at run-time but they are treated the same at compile time (the CLR doesn't differentiate between the two when it creates IL for ref and out).
- class Example1 {
- // Compiler error: "Cannot define overloaded
- // methods that differ only on ref and out".
- public void SampleMethod(out int i) {}
- public void SampleMethod(ref int i) {}
- }
However, method overloading can be done, if one method takes a ref or out argument and the other method takes a simple argument. The following example is perfectly valid to be overloaded.

Asfend YarPosted Feb 27, 2016, 2:04 AM
nice
Pushkar DudhalPosted Jul 22, 2015, 11:43 AM
Nice article...
Abhishek YadavPosted Jul 8, 2015, 6:44 PM
Good Start Sharad..
Nitesh KejriwalPosted Jul 8, 2015, 2:22 AM
Great article to start with
Sounik ChandraPosted Jul 4, 2015, 12:44 AM
Nice work dude
SharadPosted Jun 30, 2015, 11:46 AM
Thanks to all..
Deepak PanditPosted Jun 30, 2015, 11:12 AM
Nice one Sharad.!!!
dipika ladePosted Jun 30, 2015, 5:29 AM
Thanks Sharad..nice post...It was really helpful !
Santhakumar MunuswamyPosted Jun 29, 2015, 2:43 PM
Welcome
Santhakumar MunuswamyPosted Jun 29, 2015, 2:43 PM
Good start
Piyush SoniPosted Jun 29, 2015, 8:36 AM
Nice one
Laxmi PalPosted Jun 29, 2015, 8:33 AM
very informative..
Abhishek SaxenaPosted Jun 29, 2015, 5:22 AM
Detailed infomation, gr8 start!!
Gopi ChandPosted Jun 29, 2015, 4:16 AM
Great work..welcome to our community
Sibeesh VenuPosted Jun 29, 2015, 3:10 AM
Good one...
Sahil SharmaPosted Jun 29, 2015, 3:05 AM
Very detailed info. Welcome to C# Corner
Shivang DubeyPosted Jun 29, 2015, 2:23 AM
really worth Sir!
Pankaj Kumar ChoudharyPosted Jun 29, 2015, 2:21 AM
Really Nice Start Sir.............