October 29, 2011

Difference between a.Equals(b) and a == b?

Simply we could say,
a==b  checks equality of values
a.Equals(b))  checks the equality of references(objects)

Value Types :
When a & b are of same data type
int a = 1;
int b = 1;
Console.WriteLine("a==b > {0}", a == b);// Returns true
Console.WriteLine("a.Equals(b) > {0}", a.Equals(b));// Returns true
When a & b are of different data types
int a = 1;
long b = 1;
Console.WriteLine("a==b > {0}", a == b);// Returns true
Console.WriteLine("a.Equals(b) > {0}", a.Equals(b));// Returns false
It shows that a.Equals(b) not only checks for content, but also their data types.

Reference Types :
Compare StringBuilder objects.
StringBuilder a = new StringBuilder("testing");
StringBuilder b = new StringBuilder("testing");
Console.WriteLine("a==b > {0}", a == b);// Returns false
Console.WriteLine("a.Equals(b) > {0}", a.Equals(b));// Returns true
a==b returns false, because these are two different objects refenreces
a.Equals(b) returns true, because there content/values are equal


Lets consider a custom class Person objects.
public class Person
{
 string Name;

 public Person(string name)
 {
  Name = name;
 }
}

Person a = new Person("Person");
Person b = new Person("Person");
Console.WriteLine("a==b > {0}", a == b);// Returns false
Console.WriteLine("a.Equals(b) > {0}", a.Equals(b));// Returns false
a==b returns false, similaly like StringBuilder example, as two different objects refenreces
a.Equals(b) returns false,  Unlike StringBuilder example, because here content/values are not checking by-default, in order to check the internal contents of objects we have to put our custom logic, as in next example.


Lets add our own Equals() method override to put logic to compare internal content of objects. We are checking the Name of both objects.
So now Person class will look like:
public class Person
{
 string Name;

 public Person(string name)
 {
  Name = name;
 }

 public override bool Equals(object obj)
 {
  if (obj.GetType() != this.GetType())
  {
   return false;
  }

  Person p = obj as Person;
  return Name.Equals(p.Name);
 }

 public override int GetHashCode()
 {
  return base.GetHashCode();
 }
}

Person a = new Person("Person");
Person b = new Person("Person");
Console.WriteLine("a==b > {0}", a == b);// Returns false
Console.WriteLine("a.Equals(b) > {0}", a.Equals(b));// Returns true
a.Equals(b) now returns true, because now its checking Name of both objects for equality.

Moreover if you want to put cusomt checking for == operator, you even can do this by overloading ==operator.

In next example we add two overloads for ==operator and !=operator in Person class :
public static bool operator ==(Person a, Person b)
{
 // If both are null, or both are same instance, return true.
 if (System.Object.ReferenceEquals(a, b))
 {
  return true;
 }

 // If one is null, but not both, return false.
 if (((object)a == null) || ((object)b == null))
 {
  return false;
 }

 return a.Name.Equals(b.Name);
}

public static bool operator !=(Person a, Person b)
{
 return !(a == b);
}

Person a = new Person("Person");
Person b = new Person("Person");
Console.WriteLine("a==b > {0}", a == b);// Returns true
Console.WriteLine("a.Equals(b) > {0}", a.Equals(b));// Returns true
Now both techniques will return true, because both are checking the same data.

For further guidelines about overloading Equals () or operator overloading, please visit MSDN:
http://msdn.microsoft.com/en-us/library/ms173147%28v=vs.80%29.aspx

No comments:

Post a Comment