这是一个goes to
运算符(或lambda 运算符),它在lambda 表达式(创建匿名方法)中用于将输入变量与 lambda 主体分开。
在您的示例students.Find(i => i.Id== id)
输入变量i
转到 lambda 主体i.Id == id
(即作为匿名方法参数传递)。
另请查看List<T>.Find
您正在使用的方法。它接受类型的谓词T
,在您的情况下是Predicate<Student>
。Predicated 是一个委托,它表示定义一组标准并确定指定对象是否满足这些标准的方法。它有以下签名:
public delegate bool Predicate<in Student>(Student obj)
因此,您需要传递一个方法,该方法接受一个学生对象并返回一个布尔值。您可以为此创建正常的命名方法:
private bool IsStudentHasIdEqualTo5(Student s)
{
return s.Id == 5;
}
并以这种方式使用它:
Student aStudent = students.Find(IsStudentHasIdEqualTo5);
但是您需要验证不同的 id 值。有两个选项 - 在您的类中创建字段,这将在学生谓词方法中可用,或者创建类,它将具有此方法和字段:
class StudentSearcher
{
private int _id; // capture id
public StudentSearcher(int id)
{
_id = id;
}
// method has same signature as bool Predicate(Student obj)
public bool VerfyId(Student s)
{
return s.Id == _id;
}
}
现在您可以使用这个命名方法并id
为学生验证提供不同的值:
var searcher = new StudentSearcher(id);
Student aStudent = students.Find(searcher.VerfyId);
但是为每次搜索创建这样的方法和类并不是很有效。这就是我们有委托(和 lambdas)的原因。无需声明新的命名方法,您可以在需要的地方创建没有名称(匿名)的方法,编译器将为您生成通常的命名方法:
Student aStudent = students.Find(delegate(Student s) {
return s.Id == id;
});
完全相同的代码可以用 lambda 语法编写(省略了委托关键字,推断参数类型,goes to
用于分隔参数和方法体的运算符,也省略了返回关键字):
Student aStudent = students.Find(s => s.Id == id);
这里的神奇之处在于编译器将在幕后生成如上图所示的类。该类将具有带有谓词签名的方法,并且还将具有用于捕获的字段以id
进行搜索。