Func <t,tresult>如何工作?</t,tresult>

时间:2009-07-31 16:23:40

标签: c# lambda

我正在创建一个Distinct扩展方法,我可以传递如下标准。

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

我从网上获得了代码,但我很难理解Func<T, TResult>的目的。另外,当我说p => p.Name我发送String Name或发送完整的Person对象时?这是新的Distinct方法:

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

以下是用法:

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

3 个答案:

答案 0 :(得分:34)

执行此操作时:

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

你基本上是在动态创建一个函数(using lambda expressions),如下所示:

string theFunction(Person p)
{
    return p.Name;
}

这是一个适合Func<Person,String>代表签名的函数。 Distinct方法可以使用一个委托(基本上是一个函数指针),它用来确定一个元素是否是不同的 - 在你的情况下,只有唯一的字符串(由上面的函数返回)才会被认为是“不同的”元素。此委托在可枚举的“人员”的每个元素上运行,并使用这些函数的结果。然后它从这些元素创建一个序列(IEnumerable<Person>)。

答案 1 :(得分:8)

Func<T, TResult>

定义一个函数,它接受一个参数(类型为T)并返回一个对象(类型为TResult)。

在你的情况下,如果你想要一个带有Person对象并返回一个字符串的函数......你想要

Func<Person, string>

相当于:

string Function(Person p)
{
    return p.Name;
}

答案 2 :(得分:0)

如果两个人的姓名相同,你就会回到不同的人身上

如果您需要一组不同的名称,可以使用:

IEnumerable<String> names = persons.Select(p => p.Name).Distinct();