下面的代码不会编译:
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;
}
}
但是,如果我更换变量&#34; theLambda&#34;直接与lambda,然后它工作得很好。这里发生了什么? (要温柔,我是新手)。非常感谢你提前! (1)我阅读了错误信息,但对我来说并不意味着什么 (2)是的,我可以使用 compile()关键字使其与Predicate一起使用,但这不是问题。
编辑:为什么有人会对此进行投票?问题并不是那么糟糕,因为问题领域确实不具有逻辑性质。真的是人。
答案 0 :(得分:1)
它的工作原理是因为如果你声明lambda内联,编译器会隐式地为它指定正确的类型,即Predicate<Person>
。您不必明确告诉编译器lambda类型,因为它已经知道它应该采用Person
并在{{1}上调用bool
时返回FindAll
}}
List<Person>
您也可以使用具有相同功能的foreach (Person pers in PersonList.FindAll(p => p.Year >= 1992))
{
Console.WriteLine(pers.Name);
}
- LINQ方法使其更具可读性:
Enumerable.Where
来自msdn:
编写lambdas时,通常不必指定类型 输入参数因为编译器可以根据类型推断出类型 lambda body,参数的委托类型和其他因素 在C#语言规范中描述。对于大多数标准 查询运算符,第一个输入是元素的类型 源序列。因此,如果您要查询
foreach (Person pers in PersonList.Where(p => p.Year >= 1992)) { Console.WriteLine(pers.Name); }
,那么 输入变量被推断为IEnumerable<Customer>
对象
令人困惑的部分是,Customer
在逻辑上是Predicate
,它接受某种类型Func
的对象并返回T
,但由于某种原因,这种输入不会#39;工作,你必须使用bool
。声明lambda函数inline避免了这种混乱,因为你只需编写lambda体并让编译器自己推断出类型。
答案 1 :(得分:0)
FindAll需要Predicate
而不是Function
,如方法定义Array.FindAll<T> Method (T[], Predicate<T>)
中所示
当您尝试传递theLambda
时,它会尝试传递一个Function,当方法需要谓词时。您可以尝试将theLambda定义为
Predicate<Person> theLambda = (p) => p.Year >= 1992;
Predicate是一个函数,它返回一个布尔值,这是FindAll方法过滤结果所需的。
答案 2 :(得分:-1)
根据答案here,您可以执行以下操作。
foreach (Person pers in PersonList.FindAll(new Predicate<Person>(theLambda)))