Call by Value and Call by Reference in C#

Call by Value and Call by Reference in C# with Examples

In this article, I am going to discuss Call by Value and Call by Reference in C# with Examples. Please read our previous article where we discussed User-Defined Functions in C# Language with Examples.

Call by Value and Call by Reference in C#:

It is a common question which is asked by interviewers in interviews “What is Pass by Value and What is Pass by Reference” or “What is the difference between Pass by Value and Pass by Reference”. Most beginner-level developers or intermediate-level developers have misconceptions about it and they answer it wrong during interviews. They generally say when we pass primitive types they are passed by value and when we pass reference types they are passed by reference. This answer is wrong. So, today I will explain to you the real difference between them.

Call By Value in C# with Examples

In .NET Framework, by default, all the objects are called by value not call by reference. So, whether it is a Value Type (Primitive data types like int, char, double, etc.) or Reference Data Type (class, interface, delegate, string, etc.), they are by default going to be called by value.

Let us understand Call by Value in C# with some examples. Consider the following Example. In the following example, I am showing value type.

int a = 15;
int b = a;
b = 30;
Console.WriteLine(a);

So, what will be printed on Console?

If your answer is 15, then you are absolutely right because int is a value type, it is passed by value, which means for the above code the variable a has stored the value 15 in it. When we create the variable b and assign it a. The value of a is copied to b and after that, if we change b, it will not affect a. This is because we have copied the value of a to b, why the variable a is to be changed.

Example to Understand Call By Value with Value Types in C#:
using System;
namespace FunctionsDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 15;
            int b = a;
            b = 30;
            Console.WriteLine(a);
            Console.ReadKey();
        }
    }
}

Output: 15

Pictorial Representation of Call by Value in Value Types in C#

Pictorial Representation of Call by Value in Value Types in C#

The same thing is also happening when we pass value types to methods. For a better understanding, please have a look at the below example. Here, we have created a method called UpdateValue that updates the value of an int variable b to 30.

Private static void UpdateValue(int b)
{
     b = 30;
}

Now, let us call this method using our previous example.
int a = 15;
UpdateValue(a);
Console.WriteLine(a);

So, what will be printed on Console now?

Yes, it will still print 15 in the console as I already said that value is copied, so when the UpdateValue method is called, a variable value is copied to variable b so changing variable b does not change the variable a.

Example to Understand Call By Value with Value Types in C#
using System;
namespace FunctionsDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 15;
            UpdateValue(a);
            Console.WriteLine(a);
            Console.ReadKey();
        }

        private static void UpdateValue(int b)
        {
            b = 30;
        }
    }
}

Output: 15

Call by Value with Reference Types in C#

To understand Call by Value with Reference Types in C#, I have created the following Employee class. We already know that class is a reference data type.

public class Employee  
{  
    public int EmployeeID  
    {  
        get;  
        set;  
    }  
    public string Name  
    {  
        get;  
        set;  
    }  
}  

Then We create an instance of the Employee class i.e. Emp1 and set its two properties. Next, we assign it (Emp1 instance) to another instance of the Employee class i.e. Emp2, and change the Name property and then we print EmployeeID and Name on Console to check what is printed:

Employee Emp1 = new Employee()   
{  
    EmployeeID = 1001,  
    Name = "James"  
};  
Employee Emp2 = Emp1;  
Emp1.Name = "Smith";  
Console.WriteLine($"Emp1 Name = {Emp1.Name}");
Console.WriteLine($"Emp2 Name = {Emp2.Name}");

When we create Instance of Employee class, an object is created inside the heap memory and memory is allocated to it and we are storing a reference to that memory location in the Emp1 reference variable mostly in stack memory so that we can use it further, otherwise, it will get lost in the memory. So, we need to keep a reference to it to perform the different operations in memory.

When we assign Emp1 to Emp2 reference of the object memory location that Emp1 is holding is copied to Emp2. Now we have two separate copies of reference but they both are pointing to the same memory location which means they both are referencing the same memory location. So, changing the value of the Name property will change the value in the object in memory to which we have a reference in Emp1 and Emp2. So, “Smith” will be printed on the console for both references.

Example to Understand Call by Value with Reference Types in C#
using System;
namespace FunctionsDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Employee Emp1 = new Employee()
            {
                EmployeeID = 1001,
                Name = "James"
            };
            Employee Emp2 = Emp1;
            Emp1.Name = "Smith";
            Console.WriteLine($"Emp1 Name = {Emp1.Name}");
            Console.WriteLine($"Emp2 Name = {Emp2.Name}");
            Console.ReadKey();
        }
    }

    public class Employee
    {
        public int EmployeeID
        {
            get;
            set;
        }
        public string Name
        {
            get;
            set;
        }
    }
}
Output:

Example to Understand Call by Value with Reference Types in C#

Pictorial Representation of Call by Value with Reference Types in C#

Pictorial Representation of Call by Value with Reference Types in C#

We can also get the same behavior using a method. Please have a look at the below method. This method changes the Name property of an Employee.
public static void UpdateName(Employee Emp)
{
      Emp.Name = “Smith”;
}

Now, let us call this UpdateName method to change the name.
Employee Emp1 = new Employee()
{
      EmployeeID = 1001,
      Name = “James”
};
UpdateName(Emp1);
Console.WriteLine($”Emp1 Name = {Emp1.Name}”);

When we are passing reference Emp1 of the Employee object to the UpdateName method, the reference of the memory location is copied to the local object Emp of the method UpdateName, but both (Emp1 and Emp) are pointing to the same memory location which means they both are having reference to the same memory location. So, changing the value of the Name property will change the value in the object in memory and the changes will reflect both the references i.e. Emp1 and Emp, and the updated value Smith will print on the console.

Example to Understand C# Call by Value with Reference Types:
using System;
namespace FunctionsDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Employee Emp1 = new Employee()
            {
                EmployeeID = 1001,
                Name = "James"
            };
            UpdateName(Emp1);
            Console.WriteLine($"Emp1 Name = {Emp1.Name}");
            Console.ReadKey();
        }

        public static void UpdateName(Employee Emp)
        {
            Emp.Name = "Smith";
            Console.WriteLine($"Emp Name = {Emp.Name}");
        }
    }

    public class Employee
    {
        public int EmployeeID
        {
            get;
            set;
        }
        public string Name
        {
            get;
            set;
        } 
    }
}
Output:

Example to Understand C# Call by Value with Reference Types

Pictorial Representation of the above Example:

Example to Understand C# Call by Value with Reference Types

When the UpdateName(Emp1) is called, as it is referring to the same memory location, it will update the Name property of the Employee object to “Smith”. For better understanding, please have a look at the below diagram.

Call by Value and Call by Reference in C# with Examples

What would happen if we set the Emp to null inside the UpdateName method as follows?

public static void UpdateName(Employee Emp)
{
      Emp = null;
}

Now, if you are thinking that you will get a Null Reference Exception in the main method in the WriteLine statement where you print the Name, then you are wrong, and if you are thinking that it will output James, then you are right and you have understood that reference is passed by value in C# not by reference.

Complete Example Code:
using System;
namespace FunctionsDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Employee Emp1 = new Employee()
            {
                EmployeeID = 1001,
                Name = "James"
            };
            UpdateName(Emp1);
            Console.WriteLine($"Emp1 Name = {Emp1.Name}");
            Console.ReadKey();
        }

        public static void UpdateName(Employee Emp)
        {
            Emp = null;
        }
    }

    public class Employee
    {
        public int EmployeeID { get; set; }
        public string Name { get; set; }
    }
}

Output: Emp1 Name = James

Pictorial Representation of the above Example:

Call by Value and Call by Reference in C# with Examples

As you can see in the above image, when we set Emp = null; then the Emp reference is deleted. But still, the Emp1 is a reference to the Employee object. This is Call by Value mechanism in C#. Now, I hope you understand the Call by Value using both value type and reference type in C# with Examples. If we want to make Emp also null, then you have to pass it to the method via reference which is done in C# using ref Keyword i.e. nothing but Call by Reference in C#. Let us understand Call by Reference in detail.

Call By Reference in C# with Examples

Let us understand Call by Reference with both value type and reference type in C# with examples. For call by reference, we need to prefix the parameter with the ref keyword. I will explain to you Call By Reference using the same examples that we discussed in Call by Value so that it will be easier for you to understand the concept as well as understand the differences between them.

Call by Reference with Value Types in C#

We will use the same example but this time we will be calling by reference. So, we need to prefix the variable with the ref keyword. So, let us modify the UpdateValue method signature as follows. Here, you can see, instead of int b, now are using ref int b. Here, we have added the ref keyword with the input parameter which means when we call this method, the argument must be passed by reference.

private static void UpdateValue(ref int b)
{
       b = 30;
}

Now we will use the same code to call this UpdateValue method but we have to use the ref keyword before the argument name while calling the method as it is passed by reference, otherwise, we will get a compile-time error.

int a = 15;
UpdateValue(ref a);
Console.WriteLine(a);

This will print 30 on the console because we are using the ref keyword. In the above example when the UpdateValue method is called the incoming parameter of it has the same memory address as the passed argument that’s why modifying the value of b would reflect the change in a as well. In this case, the new memory location is not created for the method parameter. So, changing the value of it will reflect the variable that is passed from the calling side.

Example to Understand Call by Reference in C# with Value Types:
using System;
namespace FunctionsDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            int a = 15;
            UpdateValue(ref a);
            Console.WriteLine(a);
            Console.ReadKey();
        }

        private static void UpdateValue(ref int b)
        {
            b = 30;
        }
    }
}

Output: 30

Call by Reference with Reference Types in C#

Now, we will see the same thing with the reference type. The behavior is going to be the same for reference types as well. We are also going to work with the same example, that we worked with Call by Value with Reference Type. So, first, modify the signature of the UpdateName method as follows to take the parameter as a reference. Just need to specify the ref keyword.

public static void UpdateName(ref Employee Emp)
{
       Emp = null;
}

Now, in the main method, while calling the UpdateName method, we also need to prefix the variable with the ref keyword as follows:

Employee Emp1 = new Employee()
{
        EmployeeID = 1001,
        Name = “James”
};
UpdateName(ref Emp1);
Console.WriteLine($”Emp1 Name = {Emp1.Name}”);

Example to Understand Call by Reference in C# with Reference Type:
using System;
namespace FunctionsDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Employee Emp1 = new Employee()
            {
                EmployeeID = 1001,
                Name = "James"
            };
            UpdateName(ref Emp1);
            Console.WriteLine($"Emp1 Name = {Emp1.Name}");
            Console.ReadKey();
        }

        public static void UpdateName(ref Employee Emp)
        {
            Emp = null;
        }
    }

    public class Employee
    {
        public int EmployeeID { get; set; }
        public string Name { get; set; }
    }
}

Now, when the UpdateName name method sets the Emp to null, this also sets the Emp1 to null. This is because instead of passing the reference by value (in that a new reference memory location is created which points to the same object) it is passed by reference, so in this case, a new copy of the reference is not created but the reference of Emp1 is passed to the method. So, when you run the above code, you will get a runtime error as shown in the below image.

Example to Understand Call by Reference in C# with Reference Type

Note: If you want to achieve Call by Reference in C#, you must have to use either the out or ref keyword, regardless of whether the argument type is a value type or a reference type.

Difference between Call by Value and Call by Reference in C#:

The most important point that you need to remember is that in C#, all objects/values are passed by value by default, not by reference, regardless of whether they’re Value Types or Reference Types. With this kept in mind, let us proceed and see the differences.

Difference between Call by Value and Call by Reference in C#

Call By Value in C#:
  1. In Pass by Value, the copy of the original variable is passed to the called function.
  2. In Call by Value, the value of the original parameter is copied into the parameter of the function. As a result, if we do any modifications to formal parameters, they don’t have any impact on the actual parameter.
  3. It will not allow you to change the actual variables using function calls.
  4. The memory location referred to by formal parameters and actual arguments is different.
  5. It doesn’t require a ref or out keyword in C#.
Call By Reference in C#:
  1. In Pass by Reference, the reference of the variable is passed to the called function.
  2. In Call by Value, the argument and the given parameter both point to the same address. As a result, any changes made to any of the function’s arguments are reflected in the passed parameter.
  3. It allows you to change the actual variables using function calls.
  4. The memory location referred to by formal parameters and actual arguments are the same
  5. It requires a ref or out keyword to achieve call by reference in C#.

In the next article, I am going to discuss Recursion in C# with Examples. Here, in this article, I try to explain Call by Value and Call by Reference in C# with Examples. I hope you enjoy this Call by Value and Call by Reference in C# with Examples article. I would like to have your feedback. Please post your feedback, question, or comments about this article.

Leave a Reply

Your email address will not be published.