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.