Como o Func <T, TResult> funciona?

Eu estou criando um método de extensão distinto onde posso passar os critérios como o seguinte.

persons.Distinct(p => p.Name); 

Eu tenho o código da web, mas estou tendo dificuldade em entender o propósito deFunc<T, TResult>. Além disso, quando eu digop => p.Name estou enviando oString Name ou estou enviando o completoPerson objeto? Aqui está o novo método Distinto:

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(); 
    }
}

E aqui está o uso:

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);
    }
}

questionAnswers(3)

yourAnswerToTheQuestion