Tuesday, February 9, 2016

Reference type modification vs change of reference

Shout it kick it on DotNetKicks.com
Post is regarding misconception related to modifying reference type variable and assigning new reference object to reference type variable.

Let’s understand misconception by using code, below is customer class created to understand it.

Public class Customer 
{
 Public int ID{get; set;}
 Public string Name {get; set;}
}

Modification of Reference type
 
Customer cust = new Customer { ID = 1, Name = "abc" }; //defines new class 
Console.WriteLine("cust name : " + cust.Name);
cust.Name = "xyz"; //modifies value of name field and modifies cust variable
Console.WriteLine("modified cust name : " + cust.Name);

Above code creates new object of customer class and modifies it.

Customer cust1 = cust; //cust1 now has reference to cust
cust1.Name = "abc xyz"; // modification to Name field of cust1 modifies both cust1 and cust
Console.WriteLine("after cust1 modification name " );
Console.WriteLine("cust name : " + cust.Name);
Console.WriteLine("cust1 name : " + cust1.Name);

Output


Above code assigns reference of already created object cust to cust1. Because cust1 holding reference to same object as cust1 modification to cust1 also change cust. This means both cust and cust1 points only to one object.




Change of Reference i.e. Assigning new reference type object

But what happens when assigns null to cust variable

cust = null;
Console.WriteLine("after cust=null");
if (cust==null)
   Console.WriteLine("cust is null ");
Console.WriteLine("cust1 name : " + cust1.Name);

Ouput


Now most of developer thinks as cust is null than cust1 is also null. But this is not true because when you give new reference to cust , both cust and cust1 point to different location.



Assigning null cust variable is can also be as below

Customer cust = new Customer { ID =2 , Name =”customer abc”}

So when you assign new value to any reference its point to new memory location i.e. new object. Which also means that assigning new value to reference variable is doesn’t affect old reference variable.

What happens in case of method?

Now Consider scenario where developer pass reference variable to method

Modification of Reference type

Customer cust = new Customer { ID = 1, Name = "abc" }; //defines new class 
Console.WriteLine("cust name : " + cust.Name);
Program p = new Program();
p.ChangeCustomer(cust);
Console.WriteLine("modified cust name after call to changecustomer : " + cust.Name);

public void ChangeCustomer(Customer cust)
{
     cust.Name = "xyz"; //modifies value of name field and modifies cust variable
     Console.WriteLine("modified cust name in changecustomer : " + cust.Name);
}

Above code defines new customer object and pass customer object to method which does modification to object.

Method modifies customer name, so does it modifies customer object also. Output below prints modified customer name in method and same name after call returns to caller.

So this is similar to case discussed above.

Output 



Change of Reference i.e. Assigning new reference type object

Now consider below scenario

Customer cust = new Customer { ID = 1, Name = "abc" }; //defines new class 
Console.WriteLine("cust name : " + cust.Name);
Program p = new Program();
p.ChangeCustomer1(cust);
Console.WriteLine("modified cust name after call to changecustomer1 : " + cust.Name);

public void ChangeCustomer1(Customer cust)
{
    cust = new Customer { ID = 1, Name = "abc xyz" };
    Console.WriteLine("modified cust name in changecustomer1 : " + cust.Name);
}  

Above code defines new customer object and pass customer object to method which does modification to object.

Method in this code assigns new customer object to pass cust variable. So it print output as below



Output prints different name. Reason behind this is method doesn’t modify varible but it’s changing reference value it points by assigning new customer object.

So this is similar to case discussed above.

Solution to above is either return newly created object as below

public Customer ChangeCustomer1(Customer cust)
{
    cust = new Customer { ID = 1, Name = "abc xyz" };
    Console.WriteLine("modified cust name in changecustomer1 : " + cust.Name);
    return cust;
}

Or make use of ref with variable name

public void ChangeCustomer1(ref Customer cust)
{
    cust = new Customer { ID = 1, Name = "abc xyz" };
    Console.WriteLine("modified cust name in changecustomer1 : " + cust.Name);
}

Conclusion 

Above discussion it’s clear that modification to reference variable happens when you do change in original reference variable and assigning new object to variable does modify the reference i.e. memory location object points to.