Lambda在FindAll中有效,但在将其用作Func(或表达式)时无效
本文关键字:Func 表达式 无效 有效 FindAll Lambda | 更新日期: 2023-09-27 18:20:12
下面的代码无法编译:
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()关键字使它与谓词一起工作,但这不是问题所在。
编辑:为什么会有人投反对票?这个问题一点也不坏,因为问题域实际上不是逻辑性质的。真正的人
它之所以有效,是因为如果在内联中声明lambda,编译器会隐式为其指定正确的类型,即Predicate<Person>
。您不必显式地告诉编译器lambda类型,因为它已经知道,如果您在List<Person>
上调用FindAll
,它应该接受Person
并返回bool
。
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:
在编写lambda时,通常不必为输入参数,因为编译器可以根据lambda主体、参数的委托类型和其他因素如C#语言规范中所述。对于大多数标准查询运算符,第一个输入是源序列。因此,如果您正在查询
IEnumerable<Customer>
,那么输入变量被推断为Customer
对象
令人困惑的是,Predicate
在逻辑上是Func
,它接受某种类型的T
对象并返回bool
,但由于某些原因,这种类型不起作用,您必须使用Predicate<T>
。内联声明lambda函数可以避免这种混淆,因为您只需编写lambda主体并让编译器自己推断类型。
FindAll需要Predicate
,而不是方法定义Array.FindAll<T> Method (T[], Predicate<T>)
中的Function
当您尝试传递theLambda
时,它就是在尝试传递一个Function,而该方法需要一个Predicate。您可以尝试将Lambda定义为
Predicate<Person> theLambda = (p) => p.Year >= 1992;
谓词是一个返回布尔值的函数,这是FindAll方法过滤结果所需要的。
根据这里的答案,您可以执行以下操作。
foreach (Person pers in PersonList.FindAll(new Predicate<Person>(theLambda)))