Introduction

Hello folks,

As programmers, we come across methods/functions within the day or 2 of learning coding. I believe you are familiar with methods/functions in C#. The method may or may not return a value. But if they do return a value, they are restricted to one value. They can not return more than one value. Of course, we can use tuple in this case but again you have to store a result of a method in a tuple type only. Then access the tuple using item1 & item2. That's too complicated.

So there is another way to deal with this situation...

Now let's understand the difference between pass by value & pass by reference.

We will get a better understanding of their behavior with a live example.

Let's see how the compiler treated the ref parameter.

As per the output, only the ref parameter's value changed.

NOTE: The object type is a reference type, i.e. even if you don't mention a ref keyword, the compiler still treats it as a ref parameter.

Let's see this in action: say we have a Phone class & we are trying to update its price with 2 methods, one which has a ref parameter & another one without the ref parameter.

using I_Cant_See_Sharp.Apple;  
using System;  
  
namespace I_Cant_See_Sharp  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            Phone IPhone = new Phone() { Name = "XR", OS = "IOS 14" };  
            Console.WriteLine("---------------------------------------------- Pass by value ------------------------------------------------");  
            Console.WriteLine("IPhone's price Pass By Value: "+ IPhone);  
            GetPhonePrice(IPhone);  
            Console.WriteLine("IPhone's price after Pass By Value: "+ IPhone);  
  
            Console.WriteLine(Environment.NewLine);  
            Phone IPhone2 = new Phone() { Name = "XR", OS = "IOS 14" };  
            Console.WriteLine("----------------------------------------------   Pass by ref ------------------------------------------------");  
            Console.WriteLine("IPhone's price Pass By Ref: " + IPhone2);  
            GetPhonePriceWithRef(ref IPhone2);  
            Console.WriteLine("IPhone's price after Pass By Ref: " + IPhone2);  
  
        }  
  
        static void GetPhonePrice(Phone Phone)  
        {  
            Phone.Price = 60000;  
        }  
        static void GetPhonePriceWithRef(ref Phone Phone)  
        {  
            Phone.Price = 60000;  
        }  
    }  
}

Let's see if we are correct in this case or not

It worked as expected!

In C# we pass ref & out parameter as a reference, not as a value.

Remember, In the example of calculating GST, we used a basePrice variable as a ref parameter, we have already initialized the value of a basePrice & then we passed it to a method.

What if don't initialize the value first & we pass it to a method?

We have a compile-time error: which is not allowing us to pass the unassigned variable.

In order to overcome this, we have an out parameter.

out parameter

class Program  
{  
    static void Main(string[] args)  
    {  
        double basePrice;  
         
        Console.WriteLine("----------   Pass by out ------------");  
        GetGST_AffectedPriceWithOut(out basePrice);  
        Console.WriteLine("Price after GST: " + basePrice);  
    }
    static void GetGST_AffectedPriceWithOut(out double basePrice)  
    {  
        basePrice = 15000;  
        basePrice += (0.18 * basePrice);  
    }  
} 

Let's see if this works or not:

Works, Fine!

Let's not initialize the variable inside a method, will we able to proceed?

The answer is No, we got a compile-time error: unable to use the unassigned out parameter.

So we always need to initialize an out parameter inside a method before using it.

But it is only applicable to the primitive data types.

Let's see a real-time example of out parameter for the object type,

using I_Cant_See_Sharp.Apple;  
using System;  
  
namespace I_Cant_See_Sharp  
{  
    class Program  
    {  
      
        static void Main(string[] args)  
        {  
            //APIResult will only be initialized after API Call  
            //So there is no way to get the details at this point  
            Phone APIResult;  
            //need to use out parameter as ref parameter needs to be initialize   
            //even normal parameter has to be initialized before calling a method.  
            GetPhoneDetails(out APIResult);  
        }  
  
       /// <summary>  
       /// Get Phone details  
       /// </summary>  
       /// <param name="APIResult"></param>  
        static void GetPhoneDetails(out Phone APIResult)  
        {  
            //Heavy API Call  
            //Phone variable gets initilize after a API call, and value gets reflected in the out parameter   
            APIResult = WebAPI.GetCall("localhost:/api/GetPhoneDetails");  
        }  
    }  
} 

Let's note down the difference we learned so far:

Ref Parameter Out Parameter
It must be initialized before passing it to the method Works with uninitialized or initialized variables
The ref parameter doesn't need to assign itself inside a method as we have passed assigned variable to a method. But it is optional, the variable can be re-assigned. It is compulsory to assign the out parameter inside a method as we have not initialized the variable while passing it to a method.
value can be updated, but it is optional. as variable already has value, it is up to the requirements whether to modify value inside a method or not. we pass uninitialized out parameter to a method, which has to be initialized inside a method. so becomes a compulsion.

Conclusion

Ref & Out both parameters have the same concept, but they are differently executed or treated by the compiler.

To know more about Out parameter, follow below articles