C# - Understand Equality For Value Type And Reference Type

Introduction

 
In this article, we are going to discuss how equality works with reference type and value type.
 
Prerequisites
 
Basic understanding of class and structure in C#.
 

How does equality work with Reference Type and Value Type?

 
The first question comes to mind is, what is a reference type and value type?
 
Value Type
 
In value type, the data value is stored in its own memory address. Eg int i= 500.
 
Examples of value types are  structure, int, char, bool, decimal, etc.
 
Reference Type
 
In reference type, it stores points of the memory location where the data values are stored.
 
Eg. string str = “Hello Kirtesh”
 
An example of a reference type is a class.
 

Equality for Value Type and Reference Type

 
Now we will discuss how equality works with a reference type,
 
Let’s discuss the below code to understand how equality works with reference type (Class) and structure type (Structure),
 
Reference type Equality
 
We will use == , Equal() or System.Obect.ReferenceEquals() for reference and value equality check. 
  1. System.Object.ReferenceEquals() – method is used to check if specific object instances are the same instance or not.
  2. == -Used to check if both objects point to the same location.
  3. Equal() Method used for ReferenceEquals().
 Let’s understand all three concepts using the below example,
  1. public class Member  
  2.   {  
  3.       public int Id { getset; }  
  4.       public string Name { getset; }  
  5.       public string Address { getset; }  
  6.   }  
  1. class Program  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5.             Member obj1 = new Member  
  6.             {  
  7.                 Id = 1,  
  8.                 Name = "Kirtesh",  
  9.                 Address = "Vadodara"  
  10.             };  
  11.             Member obj2 = new Member  
  12.             {  
  13.                 Id = 1,  
  14.                 Name = "Kirtesh",  
  15.                 Address = "Vadodara"  
  16.             };  
  17.   
  18.          Console.WriteLine("***Two Objects with same Values****");  
  19.             Console.WriteLine(obj1 == obj2);  
  20.             Console.WriteLine(obj1.Equals(obj2));  
  21.             Console.WriteLine(System.Object.ReferenceEquals(obj1, obj2));  
  22.   
  23.             Console.ReadLine();  
  24.   
  25.     }  
Output
 
 
In the above example, obj1 and obj2 have the same values and different memory locations, and the result is false because it is doing reference equities not value comparisons.
 
Now I;m assigning obj2 to obj1 in the below code with different values and checking the output. 
  1. class Program  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5.             Member obj1 = new Member  
  6.             {  
  7.                 Id = 1,  
  8.                 Name = "Kirtesh",  
  9.                 Address = "Vadodara"  
  10.             };  
  11.             Member obj2 = new Member  
  12.             {  
  13.                 Id = 2,  
  14.                 Name = "Pankaj",  
  15.                 Address = "Vadodara"  
  16.             };  
  17.   
  18.             obj1 = obj2;  
  19.   
  20.             Console.WriteLine("***Obj1 = obj 2****");  
  21.             Console.WriteLine(obj1 == obj2);  
  22.             Console.WriteLine(obj1.Equals(obj2));  
  23.             Console.WriteLine(System.Object.ReferenceEquals(obj1, obj2));  
  24.             Console.ReadLine();  
  25.         }  
  26.     }  
Output
 
 
I hope this example makes  reference equality clear. Now we will check structure equities,
 
Struct Equality
 
Let`s see the below code snippet, 
  1. public struct MyStruct  
  2.     {  
  3.         public int id { getset; }  
  4.         public string name { getset; }  
  5.     };  
  1. class Program  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5.             Console.WriteLine("*******Struct Comparison***********");  
  6.             MyStruct mystr1 = new MyStruct  
  7.             {  
  8.                 id=1,  
  9.                 name="Kirtesh"  
  10.             };  
  11.             MyStruct mystr2 = new MyStruct  
  12.             {  
  13.                 id = 1,  
  14.                 name = "Pankaj"  
  15.             };  
  16.   
  17.         //    Console.WriteLine(mystr1 == mystr2); -- compile time error  
  18.             Console.WriteLine(mystr1.Equals(mystr2));  
  19.             Console.WriteLine(System.Object.ReferenceEquals(mystr1, mystr2));  
  20.             Console.ReadLine();  
  21.         }  
  22.     }  
Output
 
 
As values are not the same, hence we got false results. Let's make the value the same for both structs and try again.
  1. class Program  
  2. {  
  3.     static void Main(string[] args)  
  4.     {  
  5.         MyStruct mystr1 = new MyStruct  
  6.         {  
  7.             id=1,  
  8.             name="Kirtesh"  
  9.         };  
  10.         MyStruct mystr2 = new MyStruct  
  11.         {  
  12.             id = 1,  
  13.             name = "Kirtesh"  
  14.         };  
  15.   
  16.     //    Console.WriteLine(mystr1 == mystr2); compiler Error  
  17.         Console.WriteLine(mystr1.Equals(mystr2));  
  18.         Console.WriteLine(System.Object.ReferenceEquals(mystr1, mystr2));  
  19.         Console.ReadLine();  
  20.     }  
  21. }  
Output
 
 
As values are the same we got true in the first case. But memory location is different in the second scenario, hence the result is false.
 
I hope this helps you to understand equality for reference and value types.