I am creating a Distinct extension method where I can pass in the criteria like the following.
persons.Distinct(p => p.Name);
I got the code from the web but I am having a hard time understanding the purpose of Func<T, TResult>. Also, when I say p => p.Name am I sending the String Name or am I sending the complete Person object? Here is the new Distinct method:
public static class ExtensionMethods
{
public static IEnumerable<T> Distinct<T>(
this IEnumerable<T> list, Func<T,object> checker)
{
return list.Distinct(new GenericComparer<T>(checker));
}
}
public class GenericComparer<T> : IEqualityComparer<T>
{
private Func<T, object> _checker;
public GenericComparer(Func<T,object> checker)
{
_checker = checker;
}
public bool Equals(T x, T y)
{
return _checker(x).Equals(_checker(y));
}
public int GetHashCode(T obj)
{
return _checker(obj).GetHashCode();
}
}
And here is the usage:
static void Main(string[] args)
{
var persons = new List<Person>()
{
new Person() { Id = 1, Name = "Mary"},
new Person() {Id = 2, Name="John"},
new Person() { Id = 3, Name = "Mary"}
};
var uniquePersons = persons.Distinct(p => p.Name);
foreach(var person in uniquePersons)
{
Console.WriteLine(person.Name);
}
}
When you do this:
You’re basically creating a function on the fly (using lambda expressions), that looks like this:
This is a function that fits the signature of a
Func<Person,String>delegate. The Distinct method can take a delegate (basically a function pointer) which it uses to determine whether or not an element is distinct – in your case, only unique strings (returned by the function above) will be considered “distinct” elements. This delegate is run on each element of your “persons” enumerable, and the results of those functions are used. It then creates a sequence (IEnumerable<Person>) from those elements.