Blog Moved to http://podwysocki.codebetter.com/

Blog Moved to http://podwysocki.codebetter.com/
posts - 277, comments - 154, trackbacks - 27

My Links

News

Disclaimer
The views expressed on this weblog are mine and do not necessarily reflect the views of my employer.

All postings are provided "AS IS" with no warranties, and confer no rights.

 Subscribe in a reader


I'm test-driven!
Locations of visitors to this page

Tag Cloud

Archives

Post Categories

Image Galleries

ALT.NET

Blogs

Mailing Lists

OSS Projects

Other

  • Blog Flux Directory

User Groups

.NET - Overriding Equals and Equality Operators

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. 
 

Print | posted on Friday, June 30, 2006 1:46 PM | Filed Under [ Microsoft .NET C# ]

Feedback

Gravatar

# re: .NET - Overriding Equals and Equality Operators

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
2/13/2007 3:04 PM | Jeremiah Clark
Gravatar

# re: .NET - Overriding Equals and Equality Operators

//I think the best way is to

if( ReferenceEquals(ob1, null) && ReferenceEquals(ob2, null)) return true;
3/15/2008 3:16 AM | Kim
Gravatar

# re: .NET - Overriding Equals and Equality Operators

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
5/8/2008 7:33 AM | gopi
Gravatar

# re: .NET - Overriding Equals and Equality Operators

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
8/24/2009 3:09 PM | Nalin D.Jayasuriya
Gravatar

# re: .NET - Overriding Equals and Equality Operators

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.
6/20/2010 10:55 PM | Dave G.
Gravatar

# re: .NET - Overriding Equals and Equality Operators

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
5/31/2011 7:14 AM | liviu trifoi
Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification:
 
 

Powered by: