Problem description:
Any developer is familiar with the concept of removing duplicate numbers from a list or array. .NET 3.5 offers the new extension method “Distinct” in System.Linq namespace which can be used to remove all duplicate integers(or any value type) from a list of numbers. Here is an example:
List<int> listOfNumbers = new List<int>() { 1, 5, 4, 10, 1, 4 };
List<int> uniqueList = listOfNumbers.Distinct().ToList<int>();
Distinct method is great. is not it?
Now imagin a list of a domain objects for instance a list of User object where the User has the following signature:
class User
{
public string Username;
}
User u1 = new User() {Username="nima" };
User u2 = new User() { Username = "reza" };
User u3 = new User() { Username = "nima" };
User u4 = new User() { Username = "sanam" };
List<User> listOfUsers = new List<User>() { u1, u2, u3, u4 };
The goal is to remove duplicated User objects with the same Username. Although u1 and u3 have the same Username, from the framework point of view they
are not equal because they have different hash codes. So how can we use the Distinct method? Here is where the IEqualityComparer<T> inteface comes to account.
To define the concept of equality for complex objects, we can create a class (UserComparer) which implements the IEqualityComparer<T> interface where T is our complex business type (User here).
In UserComparer class, we will specify under which circumstance two User objects can be considered equal. This interface has two methods which we need to implement:
- Equals
- GetHashCode
The class implementation follows:
public class UserComparer : IEqualityComparer<User>
{
public bool Equals(User x, User y)
{
return x.Username == y.Username;
}
public int GetHashCode(User obj)
{
return obj.Username.GetHashCode();
}
}
Now in the client code we can use this syntax to remove the duplicate usernames from our list:
List<User> uniqueListOfUsers = listOfUsers.Distinct<User>(new UserComparer()).ToList<User>();
So uniqueListOfUsers will only contain User objects with reza, nima and sanam Usernames.
For a detailed information please visit
http://msdn.microsoft.com/en-us/library/ms132151.aspx