Saturday, January 6, 2018

C#.NET Equality : Equals() , == operator and ReferenceEquals()

There are actually two basic types of equality for objects

1. Value Equality : Two objects are equivalent if the value contains same
2. Reference Equality: Two objects are identical if it is pointing to same memory address location

1. a.Equals(b)
a)      Equals() is a virtual method on System.Object
b)      It checks  value comparison for Value Types
c)       It checks value comparison for string Type ( i.e. System.String overridden Equals() method to do value comparison )
d)        It checks memory address comparison for Reference Type
e)      It throws NullReferenceException exception when object a is null

public class StudentTest
    {
        public int Id { getset; }
        public string Name { getset; }
    }

            int a = 10;
            int b = 10;
            Console.WriteLine(a.Equals(b)); // True

            StudentTest stdObj1 = new StudentTest() {Id=1,Name="Nolan" };
            StudentTest stdObj2 = new StudentTest() { Id = 2, Name = "James" };

            Console.WriteLine(stdObj1.Equals(stdObj2)); // False

            StudentTest stdObj3 = stdObj2;
            Console.WriteLine(stdObj3.Equals(stdObj2)); // True


2. object.Equals(a,b)
a)      It is a static method (i.e. simple helper method ) on the object class
b)      It does null check before comparison so, it will not throw NullReferenceException exception when object a or b is null
c)       It returns True if both objects are null
d)      It checks  value comparison for Value Types
e)      It checks value comparison for string Type ( i.e. System.String overridden Equals() method to do value comparison )
f)         It checks memory address comparison for Reference Type
g)      It is same as a.Equals(b) except NullReferenceException Handling

            int a = 10;
            int b = 10;
            Console.WriteLine(object.Equals(a, b)); // True
 
            StudentTest stdObj1 = new StudentTest() { Id = 1, Name = "Nolan" };
            StudentTest stdObj2 = new StudentTest() { Id = 2, Name = "James" };
 
            Console.WriteLine(object.Equals(stdObj1, stdObj2)); // False
 
            StudentTest stdObj3 = stdObj2;
            Console.WriteLine(object.Equals(stdObj3, stdObj2)); // True
 
            StudentTest stdObj4 = null;
            StudentTest stdObj5 = null;
            Console.WriteLine(object.Equals(stdObj4, stdObj5)); // True

3. object.ReferenceEquals(a, b)

a) It checks memory address comparison for both Value and Reference Type
b) It expects two object type parameters. So, Passing value Types gets boxed into heap
and stored into two different memory address locations


int a = 10;
int b = 10;
Console.WriteLine(object.ReferenceEquals(a, b)); // False

int c = b;
Console.WriteLine(object.ReferenceEquals(c, b)); // False

object val1 = 10;
object val2 = val1;

Console.WriteLine(object.ReferenceEquals(val1, val2)); // True


StudentTest stdObj1 = new StudentTest() { Id = 1, Name = "Nolan" };
StudentTest stdObj2 = new StudentTest() { Id = 2, Name = "James" };

Console.WriteLine(object.ReferenceEquals(stdObj1, stdObj2)); // False

StudentTest stdObj3 = stdObj2;
Console.WriteLine(object.ReferenceEquals(stdObj3, stdObj2)); // True

StudentTest stdObj4 = null;
StudentTest stdObj5 = null;
Console.WriteLine(object.ReferenceEquals(stdObj4, stdObj5)); // True

4.      a == b
a)      It is an operator ( == ) works same as a.Equals(b)
b)      It checks  value comparison for Value Types
c)       It checks value comparison for string Type ( i.e. System.String overridden Equals() method to do value comparison )
d)        It checks memory address comparison for Reference Type

int a = 10;
int b = 10;
Console.WriteLine(a == b); // True

StudentTest stdObj1 = new StudentTest() { Id = 1, Name = "Nolan" };
StudentTest stdObj2 = new StudentTest() { Id = 2, Name = "James" };

Console.WriteLine(stdObj1 == stdObj2); // False

StudentTest stdObj3 = stdObj2;
Console.WriteLine(stdObj3 == stdObj2); // True

StudentTest stdObj4 = null;
StudentTest stdObj5 = null;
Console.WriteLine(stdObj4 == stdObj5); // True

Note:  We can provide custom equality comparison by Implementing IEquatable interface

Happy Coding :)