Geeks With Blogs
Blog Moved to http://podwysocki.codebetter.com/ Blog Moved to http://podwysocki.codebetter.com/
I've been a little absent recently due to a lot of training I have been attending.  Too much to learn in such a short period.  Anyways, let's get back to coding samples and best practices.  Even though I like to be at the software architect level, I still love keeping my hands dirty with code and giving samples here and there. 
 
Today I will be covering overloading equality operators and the Equals method.  When you are creating your entity objects or business objects, you should override and overload your Equals method as well as provide your equality operators.
 
I have seen many samples out there that just talk about overriding the Equals method, which is fine, except you should follow a certain pattern while doing so.  Take for example this Employee class I created:
 
public class Employee
{
     private string employeeId;
     private string lastName;
     private string firstName;
     private DateTime dateOfBirth;
 
     public string EmployeeId
     {
          get { return employeeId; }
          set { employeeId = value; }
     }
 
     public string LastName
     {
          get { return lastName; }
          set { lastName = value; }
     } 
    
     public string FirstName
     {
          get { return firstName; }
          set { firstName = value; }
     }
 
     public DateTime DateOfBirth
     {
          get { return dateOfBirth; }
          set { dateOfBirth = value; }
     }
 
} // class - Employee
 
Now, what we need is an easy way to determine if the objects are equal.  So, we need to override the Equals method.  That looks like the following:
 
public override bool Equals(object obj)
{
     // Check for null
     if(obj == null) return false;
 
     // Check for type
     if(this.GetType() != obj.GetType()) return false;
 
     // Cast as Employee
     Employee employee = (Employee)obj;
 
     return (this == employee);
} // method - Equals(object)
 
Now if you see what I have done, I first checked for null.  Then I checked for type.  There is another way when using the as statement, but this only applies if your particular class is marked with the sealed keyword.  An example of that is here:
 
Employee employee = obj as Employee;
if(employee == null) return false;
 
The problem with the above statement is that an extended class of Employee such as Manager could also use this and get the result of true if you left it at that, and that might not be something you want.
 
Now we can also specify an overloaded Equals method which takes an Employee object as a parameter instead of a System.Object.  This saves us casting time.
 
public bool Equals(Employee employee)
{
     // Check for null
     if(employee == null) return false;
 
     return (this == employee);
} // method - Equals(Employee)
 
As my last statement, I called the == operator.  That means I have to overload the equality operators.  Let's do that below:
 
public static bool operator ==(Employee left, Employee right)
{
     // Check for both being null
     if(left == null && right == null) return true;
 
     // Check if both not null
     if(left != null && right != null)
     {
          if(left.EmployeeId == right.EmployeeId &&
               left.LastName == right.LastName &&
               left.FirstName == right.FirstName &&
               left.DateOfBirth == right.DateOfBirth)
               return true;
     }
 
     return false;
} // operator - ==
 
As you can see with my if statement inside after checking for null, I can then compare the actual values to one another.  There are many ways to do it, but this is quick and dirty.  Now that we overloaded the == operator, we should also overload the != operator.  This code is much simpler:
 
public static bool operator !=(Employee left, Employee right)
{
     return !(left == right);
} // operator - !=
 
If I went into more detail, I could also implement the IComparable or IComparable Generic interfaces which would allow me to compare my two business objects to see which is greater, but I didn't feel it was appropriate for this time.
 
As you can see, when comparing our business objects is quite simple and .NET provides us easy ways to do it.  Sure it seems like C# 101 and such, but it's always fun to cover basics now and again. 
 
Posted on Friday, June 30, 2006 1:46 PM Microsoft , .NET , C# | Back to top


Comments on this post: .NET - Overriding Equals and Equality Operators

# re: .NET - Overriding Equals and Equality Operators
Requesting Gravatar...
Matt,
I was doing some reasearch and came across your blog. I was attempting to implement the code that you specify above, but I think I found an error with the following snippet:

public static bool operator ==(Employee left, Employee right)
{
// Check for both being null
if(left == null && right == null) return true;
...
}

This compiles but gives a StackOverflowException on the null comparisons. I believe this is because we are basically calling the function recursively forever. Left and right are both of type Employee and the == operator is calling back to the overloaded method that it just came from.
I changed the line to be (along with the next few lines that compare the objects):

if((object)left == null && (object)right == null) return true;

Is this the best way to do this, or is there another more efficient solution?

Thanks,
Jeremiah
Left by Jeremiah Clark on Feb 13, 2007 3:04 PM

# re: .NET - Overriding Equals and Equality Operators
Requesting Gravatar...
//I think the best way is to

if( ReferenceEquals(ob1, null) && ReferenceEquals(ob2, null)) return true;
Left by Kim on Mar 15, 2008 3:16 AM

# re: .NET - Overriding Equals and Equality Operators
Requesting Gravatar...
I have a doubt in using arraylist.contains()
I have a long list of strings in which I should check if it contained one specific string.
Now I want to do it using an ArrayList, I will be storing all the string elements, then I would like to check it with contains method of Arraylist is that a correct method to do it.
as shown below

Dim myarry as new ArrayList
myarry.add("one")
myarry.add("two")
...
myarry.add("fifty")

if (myarry.contains("ten"))
return true
end if
Left by gopi on May 08, 2008 7:33 AM

# re: .NET - Overriding Equals and Equality Operators
Requesting Gravatar...
Hi,

A comment on the Equals method implemention.

As a good coding practice, each method that returns a value must only have one return statement. So it's good to have a variable inside the method to keep track of the return value and return it only at the end of the method block.

Regards,

- Nalin J
Left by Nalin D.Jayasuriya on Aug 24, 2009 3:09 PM

# re: .NET - Overriding Equals and Equality Operators
Requesting Gravatar...
Nalin J,

No offense, but that is rubbish.

There is no way that maintaining a temporary variable through a whole cavalcade of if/else or switch statements for no other reason than to return it at the end anyway rather than simply returning the result as soon as you know it is better "coding practice".

Instead of adhering to strict programming dogma which, in this case, is just plain wrong, code for simplicity and ease of reading.
Left by Dave G. on Jun 20, 2010 10:55 PM

# re: .NET - Overriding Equals and Equality Operators
Requesting Gravatar...
I could bet that this method:

public static bool operator ==(Employee left, Employee right)
{
// Check for both being null
if(left == null && right == null) return true;
...
}
crashes your application if you try to use new Employee() == null, because of the recursive call inside.
left == null is recursive, because you are in the == overload.

The correct way to do it is:

// If both are null, or both are same instance, return true.
if (System.Object.ReferenceEquals(left, right))
{
return true;
}

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

//compare here the other fields
Left by liviu trifoi on May 31, 2011 7:14 AM

Your comment:
 (will show your gravatar)


Copyright © Matthew Podwysocki | Powered by: GeeksWithBlogs.net