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.
- class Example2
- {
- public void SampleMethod(int i) { }
- public void SampleMethod(ref int i) { }
- }
Or:
- class Example3
- {
- public void SampleMethod(int i) { }
- public void SampleMethod(out int i) { }
- }
Like all out parameters, an out parameter of an array type must be assigned before it is used; that is, it must be assigned by the callee.
- static void TestMethod1(out int[] arr)
- {
- arr = new int[10]; // definite assignment of arr
- }
- static void TestMethod2(ref int[] arr)
- {
- arr = new int[10]; // arr initialized to a different array
- }
- class TestOut {
- static void FillArray(out int[] arr) {
- // Initialize the array:
- arr = new int[5] {
- 1, 2, 3, 4, 5
- };
- }
- static void Main() {
- int[] theArray; // Initialization is not required
- // Pass the array to the callee using out:
- FillArray(out theArray);
- // Display the array elements:
- System.Console.WriteLine("Array elements are:");
- for (int i = 0; i < theArray.Length; i++) {
- System.Console.Write(theArray[i] + " ");
- }
- // Keep the console window open in debug mode.
- System.Console.WriteLine("Press any key to exit.");
- System.Console.ReadKey();
- }
- }
Output
- class TestRef {
- static void FillArray(ref int[] arr) {
- // Create the array on demand:
- if (arr == null) {
- arr = new int[10];
- }
- // Fill the array:
- arr[0] = 1111;
- arr[4] = 5555;
- }
- static void Main() {
- // Initialize the array:
- int[] theArray = {
- 1, 2, 3, 4, 5
- };
- // Pass the array using ref:
- FillArray(ref theArray);
- // Display the updated array:
- System.Console.WriteLine("Array elements are:");
- for (int i = 0; i < theArray.Length; i++) {
- System.Console.Write(theArray[i] + " ");
- }
- // Keep the console window open in debug mode.
- System.Console.WriteLine("Press any key to exit.");
- System.Console.ReadKey();
- }
- }
The following are some points to remember:
-
Properties cannot be passed via out or ref, since properties are actually methods.
-
There is no "boxing" when a value type is passed by reference.
-
ref / out are not considered to be a part of the method signature at compile time, so methods cannot be overloaded, if the only difference between them is that one of the methods takes a ref argument and the other takes an out argument.
Thanks for reading my article.

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.............