
.NET 3.5+A Generic Equality Comparer for LINQ (2)
LINQ operators generally use lambda expressions to control their processing and output. Some operators use IEqualityComparer<T> implementations to compare values. This article describes a generic comparer, driven by delegates, designed for use in queries.
Testing the LambdaComparer
In order to test the new comparer we need a class to compare. We'll use the same Customer class that was defined in the earlier article:
public class Customer
{
Guid _id;
string _forename;
string _surname;
public Guid Id
{
get { return _id; }
set { _id = value; }
}
public string Forename
{
get { return _forename; }
set { _forename = value; }
}
public string Surname
{
get { return _surname; }
set { _surname = value; }
}
}
If you have read the previous article you will have seen the test code, where three customers were created and compared, and where their hash codes were calculated to show that matching customers had the same hash code. We can recreate that code using the LambdaEqualityComparer<T> class, as shown below. Note the two arguments passed to the comparer's constructor, which define the actions of the Equals and GetHashCode methods.
Customer customer1 = new Customer();
customer1.Id = new Guid("12345678901234567890123456789012");
customer1.Forename = "Bob";
Customer customer2 = new Customer();
customer2.Id = new Guid("12345678901234567890123456789012");
customer2.Surname = "Smith";
Customer customer3 = new Customer();
customer3.Id = new Guid("11111111111111111111111111111111");
customer3.Forename = "Bob";
var comparer = new LambdaEqualityComparer<Customer>(
(x, y) => x.Id == y.Id, x => x.Id.GetHashCode());
bool same1and2 = comparer.Equals(customer1, customer2); // true
bool same1and3 = comparer.Equals(customer1, customer3); // false
int hash1 = comparer.GetHashCode(customer1); // -1876532676
int hash2 = comparer.GetHashCode(customer2); // -1876532676
int hash3 = comparer.GetHashCode(customer3); // 285212689
We can also try passing the comparer to a standard query operator. The code below creates a list containing the three customers. It then obtains a distinct sequence from the list. As the first and second customers have the same ID, customer2 is not present in the resultant sequence.
var customers = new List<Customer> { customer1, customer2, customer3 };
var uniqueCustomers = customers.Distinct(comparer); // Returns customer1 and customer3
16 January 2012