C# Lambda在FindAll中工作,但在将其用作Func(或表达式)时不起作用

C# Lambda在FindAll中工作,但在将其用作Func(或表达式)时不起作用,c#,lambda,expression,predicate,findall,C#,Lambda,Expression,Predicate,Findall,以下代码无法编译: 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

以下代码无法编译:

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;
    }
}  
Func theLambda=(p)=>p.年>=1992年;
foreach(PersonList.FindAll(theLambda)中的Person pers)
{
Console.WriteLine(用户名称);
}
公共阶层人士
{
公共字符串名称{get;set;}
公共整数年{get;set;}
公众人物(字符串名称,整数年)
{
this.Name=Name;this.Year=Year;
}
}  
然而,若我直接用lambda替换变量“theLambda”,那个么它就可以正常工作。这是怎么回事?(温柔点,我是新手)。提前非常感谢
(1) 我阅读了错误消息,但它对我来说没有任何意义。
(2) 是的,我可以使用compile()关键字使它与谓词一起工作,但这不是问题所在


编辑:为什么会有人否决这个?这个问题一点也不坏,因为问题域实际上并不具有逻辑性质。真的是人

FindAll需要一个
谓词
,而不是
函数
,如方法定义
Array.FindAll方法(T[]中所示, 谓词)

当您尝试传递lambda时,当方法需要谓词时,它正在尝试传递函数。您可以尝试将lambda定义为

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

谓词是一个返回布尔值的函数,这是FindAll方法过滤结果所需的。

FindAll需要一个
谓词,而不是
函数,如方法定义
Array.FindAll方法(T[]中所示, 谓词)

当您尝试传递lambda时,当方法需要谓词时,它正在尝试传递函数。您可以尝试将lambda定义为

Predicate<Person> theLambda = (p) => p.Year >= 1992;
谓词theLambda=(p)=>p.年>=1992年;
谓词是一个返回布尔值的函数,这是FindAll方法过滤结果所需的。

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

foreach(PersonList.FindAll(新谓词(theLambda))中的Person pers)
根据答案,您可以执行以下操作


foreach(PersonList.FindAll中的Person pers(new Predicate(theLambda))
它可以工作,因为如果您内联声明lambda,编译器会隐式地为它指定正确的类型,即
谓词。您不必显式地告诉编译器lambda类型,因为它已经知道,如果在
列表上调用
FindAll
,它应该使用
Person
并返回
bool

您还可以使用
可枚举。其中
-LINQ方法具有相同的功能,使其更具可读性:

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

在编写lambda时,通常不必为 输入参数,因为编译器可以根据 lambda主体、参数的委托类型和其他因素 在C语言规范中描述。对于大多数标准 查询运算符时,第一个输入是 源序列。因此,如果您正在查询一个
IEnumerable
,那么 输入变量被推断为
客户
对象


令人困惑的是,
谓词
在逻辑上是一个
函数
,它接受某种类型的
T
对象并返回一个
bool
,但由于某些原因,这种类型不起作用,您必须使用
谓词
。内联声明lambda函数可以避免这种混淆,因为您只需编写lambda主体,并让编译器自己推断类型

之所以有效,是因为如果您在内联中声明lambda,编译器会隐式地为其指定正确的类型,即
谓词
。您不必显式地告诉编译器lambda类型,因为它已经知道,如果在
列表上调用
FindAll
,它应该使用
Person
并返回
bool

您还可以使用
可枚举。其中
-LINQ方法具有相同的功能,使其更具可读性:

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

在编写lambda时,通常不必为 输入参数,因为编译器可以根据 lambda主体、参数的委托类型和其他因素 在C语言规范中描述。对于大多数标准 查询运算符时,第一个输入是 源序列。因此,如果您正在查询一个
IEnumerable
,那么 输入变量被推断为
客户
对象


令人困惑的是,
谓词
在逻辑上是一个
函数
,它接受某种类型的
T
对象并返回一个
bool
,但由于某些原因,这种类型不起作用,您必须使用
谓词
。内联声明lambda函数可以避免这种混淆,因为您只需编写lambda主体,并让编译器自己推断类型

错误消息是什么?可能是因为您使用的类型不正确。请尝试使用
谓词
。错误消息是什么?可能是因为您使用的类型不正确。试试
Predicate
。@Praveen你完全解决了我不理解的问题域!所以内联是有效的,你解释了原因。即使我传递了lambda,而不是谓词,编译器也知道该做什么。所以这是一个编译器的东西。明白了!所以当我这样做的时候:Func theLambda=(p)=>p.Year>=1992;或者这个表达式theLambda=(p)=>p.Year>=1992编译器突然不能这么做?是吗?@Valmont-Lambda只是匿名函数的名称,
谓词
,或
Func
,或
Action
是此匿名函数的类型。lambdas的全部要点是,当编译器知道它们的类型时,您不必显式地声明它们的类型