If you need to remove the duplicate items from a generic list, you can use the
LINQ 'sDistinct method and pass an instance of IEqualityComparer as an argument
to it. Using IEqualityComparer you can define your rules for identifying
duplicates.
Suppose you have a class
public class Contact
{
public string FirstName { get;
set; }
public string LastName { get;
set; }
public string EmailAddress { get;
set; }
}
And you have the requirement where you can tell
which property of your object to compare. So the comparer class goes as below
public sealed class EqualityComparer<T,
TKey> : IEqualityComparer<T>
{
private readonly Func<T,
TKey> _keySelector;
private readonly IEqualityComparer<TKey>
_keyComparer;
public
EqualityComparer(Func<T, TKey>
keySelector, IEqualityComparer<TKey>
keyComparer)
{
if (null ==
keySelector) throw new
ArgumentNullException("keySelector");
_keySelector = keySelector;
_keyComparer = keyComparer ?? EqualityComparer<TKey>.Default;
}
public
EqualityComparer(Func<T, TKey>
keySelector)
:
this(keySelector, null)
{
}
public bool Equals(T x, T y)
{
if (!GenericHelper.HasValue(x))
return !GenericHelper.HasValue(y);
if (!GenericHelper.HasValue(y)) return false;
TKey xKey = _keySelector(x);
TKey yKey = _keySelector(y);
if (!GenericHelper.HasValue(xKey)) return !GenericHelper.HasValue(yKey);
if (!GenericHelper.HasValue(yKey)) return false;
return
_keyComparer.Equals(xKey, yKey);
}
public int GetHashCode(T obj)
{
if (!GenericHelper.HasValue(obj))
return 0;
TKey key = _keySelector(obj);
if (!GenericHelper.HasValue(key))
return 0;
return _keyComparer.GetHashCode(key);
}
}
public static class EqualityComparer
{
public static IEqualityComparer<T>
Create<T, TKey>(Func<T, TKey>
keySelector, IEqualityComparer<TKey>
keyComparer)
{
if (null == keySelector) throw
new ArgumentNullException("keySelector");
return new EqualityComparer<T,
TKey>(keySelector, keyComparer);
}
public static IEqualityComparer<T>
Create<T, TKey>(Func<T, TKey>
keySelector)
{
return
Create(keySelector, null);
}
}
And sample console code:
static void Main(string[] args)
{
//create a list
of custom class
List<Contact> collection = new
List<Contact>();
//create a list
of integer items
List<int> list = new List<int>();
//populate the
lists
#region populate the lists
#endregion
//create the
custom comparers
IEqualityComparer<Contact> customComparer = EqualityComparer.Create((Contact
c) => c.EmailAddress);
IEqualityComparer<int> customComparer2 = EqualityComparer.Create((int l) => l);
//print the
distinct items form contact collection
foreach (Contact c in
collection.Distinct(customComparer))
{
Console.WriteLine("Name:
{0} {1}, Email: {2}", c.FirstName, c.LastName, c.EmailAddress);
}
//print the
distinct items from int collection
foreach (int c in
list.Distinct(customComparer2))
{
Console.WriteLine(c.ToString());
}
Console.ReadLine();
}