Ref And Out Keywords In C#

Introduction:

Before talking about ref and out keyword let`s first talk about how parameters are passed to a method in C#. By default when we pass a parameter to a method it is passed by value (copy of the data is passed to a method). But exactly what is copied depends on whether the type is value type or reference type. Int, char, double, decimal, enum etc are built in value types in C# and class, object, delegate, string etc are built in reference types in C#.

Passing value type variable as a parameter:

Value type variable in C# holds the actual value. When we pass value type parameter to a method, then we are passing copy of the value. Consider the following example:

  1. using System;  
  2.    
  3. namespace RefAndOutKeywords  
  4. {  
  5.     class Program  
  6.     {  
  7.         static void Main(string[] args)  
  8.         {  
  9.             // Int is a built in value type in C#  
  10.             int i = 10;  
  11.    
  12.             // Passing variable i to increment method as a parameter  
  13.             Increment(i);  
  14.    
  15.             Console.WriteLine("Value of variable i: "+i);  
  16.         }  
  17.    
  18.         static void Increment(int j)  
  19.         {  
  20.             j = j + 1;  
  21.         }  
  22.     }  
  23. }  
In the above example, int i is a value type variable initialized with a value of 10. When we call a method Increment() and pass the variable i as a parameter, then content of i is copied to parameter j. So variable j will be set to value of 10. In increment method we are incrementing the value of j by 1. Even though we change the value of j by 1, value of variable i will be still 10 because we are making the changes on copy of the original value of variable i. Output of above code sample is as shown below (F:1)

output

Passing reference type variable as a parameter:

Reference type variable in C# holds a pointer to an object in memory. When we pass reference type parameter to a method, then we are passing copy of the reference. To demonstrate this, let`s first create a Person class having the Name and Age properties as shown below.
  1. namespace RefAndOutKeywords  
  2. {  
  3.     public class Person  
  4.     {  
  5.         public Person()  
  6.         {  
  7.             Name = "Manoj Kulkarni";  
  8.         }  
  9.         public string Name { getset; }  
  10.         public string Age { getset; }  
  11.     }  
  12. }  
Consider the following example:
  1. using System;  
  2.    
  3. namespace RefAndOutKeywords  
  4. {  
  5.     class Program  
  6.     {  
  7.         static void Main(string[] args)  
  8.         {  
  9.             var person = new Person();  
  10.    
  11.             Console.WriteLine("Before Executing the method: "+person.Name);  
  12.    
  13.             ChangeName(person);  
  14.    
  15.             Console.WriteLine("After Executing the method: " + person.Name);  
  16.         }  
  17.    
  18.         private static void ChangeName(Person p)  
  19.         {  
  20.             p.Name = "Suhas Kulkarni";  
  21.         }  
  22.     }  
  23. }  
In the above example, variable person is a reference type variable created by instantiating Person class by using the new keyword. This person variable holds a pointer to a person object in memory. When we call a method ChangeName() and pass the variable person as a parameter, then a copy of the reference which points to person object is passed to variable p. Now we have two variables person and p pointing to the same person object in memory. In ChangeName method, we are changing the value of Name property to "Suhas Kulkarni". Initially value of Name property was "Manoj Kulkarni" which was set using the constructor of Person class. As both variables are pointing to the same person object, this change will get reflected for person variable also. Output of above code sample is as shown below (F: 2).

output

We can change this default behaviour of passing parameter by value by using the ref and out keywords in C#. Let`s go through each one of them.

Ref keyword:

The ref keyword causes a value to be passed by reference and not by value. The effect of passing the parameter by reference is that any change to the parameter in the called method is reflected in the calling method.

Points to remember for variable with ref keyword:

 

  • We need to initialize the variable before passing it as a parameter to a method.
  • We don`t need to change the value of variable in called method but if we want to change it then we can change the value of variable in called method.

Passing value type variable as a parameter with ref keyword:

Let`s use the same example which we have used for value type previously. We just need to add ref keyword before the parameter name in method definition and while calling the method as shown below.

  1. using System;  
  2.    
  3. namespace RefAndOutKeywords  
  4. {  
  5.     class Program  
  6.     {  
  7.         static void Main(string[] args)  
  8.         {  
  9.             // Int is a built in value type in C#  
  10.             int i = 10;  
  11.    
  12.             // Passing variable i to increment method as a parameter  
  13.             Increment(ref i);  
  14.    
  15.             Console.WriteLine("Value of variable i: "+i);  
  16.         }  
  17.    
  18.         static void Increment(ref int j)  
  19.         {  
  20.             j = j + 1;  
  21.         }  
  22.     }  
  23. }  
In above example, after execution of method Increment(), value of variable i will change from 10 to 11. Output of above code sample is as shown below (F: 3).

output

Passing reference type variable as a parameter with ref keyword:

Let`s use the same example which we have used for reference type previously. Only few changes we need to make in that example which are described as follows:
  • Add ref keyword before the parameter name in method definition and while calling the method.
  • Create another variable called p1 and assign variable person to p1 and pass that variable to ChangeName() method.
    1. using System;  
    2.    
    3. namespace RefAndOutKeywords  
    4. {  
    5.     class Program  
    6.     {  
    7.         static void Main(string[] args)  
    8.         {  
    9.             var person = new Person();  
    10.             var p1 = person;  
    11.    
    12.             Console.WriteLine("Before Executing the method: " + p1.Name);  
    13.    
    14.             ChangeName(ref p1);  
    15.    
    16.             Console.WriteLine("After Executing the method p1.Name: " + p1.Name);  
    17.             Console.WriteLine("After Executing the method person.Name: " + person.Name);  
    18.         }  
    19.    
    20.         private static void ChangeName(ref Person p)  
    21.         {  
    22.             p.Name="Suhas Kulkarni";  
    23.         }  
    24.     }  
    25. }  

In above example, after execution of line number 10 object reference value of variable person get copied to variable p1. Then when we call ChangeName() method with variable p1 as a parameter then actual object reference get passed to the method. So the variable p in ChangeName() method also points to the same Person object which is created in Main method at line number 9. So after the execution of method ChangeName(), we will have three variables person, p1 and p pointing to the same object in memory. Output of the above code sample is as shown below (F: 3)

output

output
Output looks same like when we have passed the reference type variable as a parameter without ref keyword. Now let`s add few more lines in ChangeName() method and check the output again. Updated code sample is as shown below.

  1. using System;  
  2.    
  3. namespace RefAndOutKeywords  
  4. {  
  5.     class Program  
  6.     {  
  7.         static void Main(string[] args)  
  8.         {  
  9.             var person = new Person();  
  10.             var p1 = person;  
  11.    
  12.             Console.WriteLine("Before Executing the method: " + p1.Name);  
  13.    
  14.             ChangeName(ref p1);  
  15.    
  16.             Console.WriteLine("After Executing the method p1.Name: " + p1.Name);  
  17.             Console.WriteLine("After Executing the method person.Name: " + person.Name);  
  18.         }  
  19.    
  20.         private static void ChangeName(ref Person p)  
  21.         {  
  22.             p.Name="Suhas Kulkarni";  
  23.    
  24.             p = new Person();  
  25.    
  26.             p.Name = "Sanket Kulkarni";  
  27.         }  
  28.     }  
  29. }  
In previous example we looked at that because of the ref keyword, actual object reference value of variable p1 ges passed to ChangeName() method and assigned to variable p. In above code sample, the actual reference value of variables p1 and p is changed to a completely new Person object which is created at line number 24. So after execution of ChangeName() method, we now have one variable person pointing to original person object which was created before calling the ChangeName() method and two variables p1 and p pointing to a completely new person object in memory which is created in ChangeName() method. Output of above code sample is as shown below (F: 4).

output
output

So the main key points to remember for reference type variable with ref keyword are as follows:
  • When we pass reference type variable without ref keyword we cannot change the actual pointer to an object.
  • When we pass reference type by using the ref keyword, then we can change the actual pointer to an object.

Out keyword:

Out keyword works the same way as the ref keyword.

Points to remember for variable having out keyword:

  • We don`t need to initialize the variable before calling the method.
  • We need to initialize a value to a variable with out keyword before the method completes the execution and return to the caller again.

Conclusion:

In this article we talked about default behaviour when we pass parameter to a method and the  of using the ref and out keyword while passing the parameter to a method. I hope you enjoyed reading the article.

Happy coding.

Read more articles on C#:


Similar Articles