Lambda 在 FindAll 中有效,但在将其用作 Func(或表达式)时无效

Lambda works in FindAll, but not when using it as an Func (or Expression)

以下代码无法编译:

Func<Person, bool> theLambda = (p) => p.Year >= 1992;

foreach (Person pers in PersonList.FindAll(theLambda))
{
    Console.WriteLine(pers.Name);
}

public class Person
{
    public string Name { get; set; }
    public int Year { get; set; }

    public Person(string Name, int Year )
    {
        this.Name = Name; this.Year = Year;
    }
}  

但是,如果我直接用 lambda 替换变量 "theLambda",那么它就可以正常工作。这里发生了什么? (温柔点,我是新手)。提前致谢!
(1) 我阅读了错误信息,但这对我来说没有任何意义。
(2) 是的,我可以通过使用 compile() 关键字使其与谓词一起工作,但这不是这里的问题。

编辑:为什么会有人对此投反对票?这个问题一点也不糟糕,因为问题域确实不是逻辑性质的。真人啊

FindAll 需要一个 Predicate 而不是方法定义 Array.FindAll<T> Method (T[], Predicate<T>)

中看到的 Function

当您尝试传递 theLambda 时,它试图传递一个函数,而该方法需要一个谓词。您可以尝试将 theLambda 定义为

Predicate<Person> theLambda = (p) => p.Year >= 1992;

谓词是一个 returns 布尔值的函数,它是 FindAll 方法过滤结果所需要的。

根据答案 here,您可以执行以下操作。

foreach (Person pers in PersonList.FindAll(new Predicate<Person>(theLambda)))

之所以有效,是因为如果您将 lambda 声明为内联,编译器会隐式为其分配正确的类型,即 Predicate<Person>。您不必明确告诉编译器 lambda 类型,因为它已经知道它应该采用 Person 和 return 如果您在 List<Person>.

foreach (Person pers in PersonList.FindAll(p => p.Year >= 1992))
{
    Console.WriteLine(pers.Name);
}

您还可以使用 Enumerable.Where - 具有相同功能的 LINQ 方法,使其更具可读性:

foreach (Person pers in PersonList.Where(p => p.Year >= 1992))
{
    Console.WriteLine(pers.Name);
}

来自 msdn:

When writing lambdas, you often do not have to specify a type for the input parameters because the compiler can infer the type based on the lambda body, the parameter’s delegate type, and other factors as described in the C# Language Specification. For most of the standard query operators, the first input is the type of the elements in the source sequence. So if you are querying an IEnumerable<Customer>, then the input variable is inferred to be a Customer object

令人困惑的部分是 Predicate 在逻辑上是一个 Func,它采用某种类型的对象 T 而 return 是一个 bool,但是由于某种原因,这种输入不起作用,您必须使用 Predicate<T>。内联声明 lambda 函数避免了这种混淆,因为您只需编写 lambda 主体并让编译器自行推断类型。