Ref And Out Keywords in C#

Before understand the ref and out keywords it is necessary to understand  what value and reference types are, so let us start with reference types.

Reference types are a pointer type that stores a memory address that points to a memory location in heap memory. Here the key point is that a reference type uses both the stack and the heap. That means it stores the address in the heap and the value is stored in the stack, so it means that without the stack their is no heap at all.

Example: All user defined  classes.
Value types are those that directly store a value inside it and that uses stack memory.

Example: All pre-defined data types. (For example int, float, double and and so on.)

KeyCapsule: for example I do like this:
  1. int x=4;  
  2. int x1=x;  
  3. then again if x=100;  
And if we print x1 the output we get is 4 only, so it cannot be changed because it holds the value directly but if a reference type changes in one type it must be reflected to another type.

Now let's start with our main topic the ref and out keywords.

Ref Keyword

The ref keyword can be used with any data type. The main purpose of the ref keyword is to make any type a reference type, in other words when we add a ref keyword in a method call then the C# compiler does not create a new variable, it just creates a copy of that type that only points to that specific variable that we declared and any changes made to that variable will be reflected in that variable. For example we do it like:
  1. int x=10;  
  2. show(ref x)  
  3. //Method declaration  
Public static show (ref int number) //Here it does not create a new variable, rather it makes a copy of that type so any changes made to it is reflected to the original variable, that's how ref is used in primitive data type.

For example:
  1. class RefDemo  
  2. {  
  3.    public static void Show(int number)  
  4.    {  
  5.       number= 23;  
  6.    }  
  7.    static void Main()  
  8.    {  
  9.       int x=10;  
  10.       Show(x);  
  11.       Console.WriteLine(x);   
  12.    }  
  13. }  
In the preceding the output is 10 because all value type variables are directly storing a value so due to this here if we print the number we get output as 23 and for x we get 10.

But it is changed when we call this method using the ref keyword. That can be as in the following:
  1. class RefDemo  
  2. {  
  3.    public static void Show(ref int number)  
  4.    {  
  5.       number= 23;  
  6.    }  
  7.    static void Main()  
  8.    {  
  9.       int x=10;  
  10.       Show(ref x);  
  11.       Console.WriteLine(x);   
  12.    }  
  13. }  
Here we got the output as 23 because the C# compiler doesn't create a variable, it makes a copy of type x. So the changes made anywhere are reflected to x.

A class or all reference type variables also do that. As we know in case of a class type without using ref also they point to the same object when we assign one object to a class variable. Consider Case 1.

Case 1
  1. class RefDemo  
  2. {  
  3.    public static void Show(GradeData data) //GradeData is class  
  4.    {  
  5.       data.name= "SURYA";  
  6.    }  
  7.    static void Main()  
  8.    {  
  9.       GradeData obj=new GradeData();  
  10.       GradeData obj1;  
  11.       obj1.name="Rajani";  
  12.       obj1=obj;  
  13.       Show(obj1)  
  14.       Console.WriteLine(obj1.name);   
  15.    }  
  16. }  
Here we got the output as "SURYA".

Consider the second case.

Case 2
  1. class RefDemo  
  2. {  
  3.    public static void Show(GradeData data) //GradeData is class  
  4.    {  
  5.       GradeData data=new GradeData();  
  6.       data.name= "SURYA";  
  7.    }  
  8.    static void Main()  
  9.    {  
  10.       GradeData obj=new GradeData();  
  11.       GradeData obj1;  
  12.       obj1.name="Rajani";  
  13.       obj1=obj;  
  14.       Show(obj1)  
  15.       Console.WriteLine(obj1.name);   
  16.    }  
  17. }  
Here the output is "Rajani" not "SURYA" because although we are sending obj1 as a parameter we cannot get "SURYA" as output because the data is now a new instance but in the first case it is only a variable.

So to make that instance also point to the same variable we use the ref keyword.

For example:
  1. class RefDemo  
  2. {  
  3.    public static void Show(ref GradeData data) //GradeData is class  
  4.    {  
  5.       GradeData data=new GradeData();  
  6.       data.name= "SURYA";  
  7.    }  
  8.    static void Main()  
  9.    {  
  10.       GradeData obj=new GradeData();  
  11.       GradeData obj1;  
  12.       obj1.name="Rajani";  
  13.       obj1=obj;  
  14.       Show(ref obj1)  
  15.       Console.WriteLine(obj1.name);   
  16.    }  
  17. }  
Here we get the output "SURYA".

Because, due to the use of the ref keyword, the C# compiler treats the data object as a copy of the obj1 type so any changes made to the data are reflected in obj1/obj.

Key Capsule

Before we use the ref keyword in a call a method, it must be initialized, whether it is a value type or a ref type.

Out keyword

The out is also used for the same purpose and we can use it for both a value type and a reference type but the following is the main difference.

Before calling the method using the ref keyword we must allocate the variable used in that method whereas for an out we need not assign the value before calling the method. In other words the C# compiler doesn't care about whether you assigned or not but it is necessary when the controller goes to a specific method, in that method we must initialize the variable before the control flows out of that method.

Another difference is that when out is used with a value type then we can return more than one value from a method at a time.

For example:
  1. class OutDemo  
  2. {  
  3.    public static void GetData(int c, out int a, out int b)  
  4.    {  
  5.       a = c + 5;  
  6.       b = c + a;  
  7.    }  
  8.    static void Main()  
  9.    {  
  10.       int a,b;  
  11.       GetData(5, out a, out b);  
  12.       Console.WriteLine(a + "\n" + b);  
  13.       Console.ReadLine();  
  14.    }  
  15. }  
Here it will print a=10 and b=15.

Last but not the list

Important Key Capsule

Remember that during compilation both the out and ref keywords are not considered by the CSC compiler, it only checks the standard language infrastructure, so if you are writing like this:
  1. public static void Getdata(ref int a)  
  2. {  
  3. }  
  4. public static void Getdata(out int a)  
  5. {  
  6. }  
And thinking that it is an overloaded method then you are wrong both are same only. Here the C# compiler does not consider ref and out as a parameter so it shows an error at runtime.

I think the preceding has given you a clear picture of ref and out.

Thanks for reading. I hope this useful for you.

Please reply with a comment if there is anything wrong or if you have a suggestion. :)

Regards,
"Suryakant"