这是一个goes to
运算符(或lambda运算符),在lambda表达式(创建匿名方法)中用于将输入变量与lambda主体分离。
在您的示例students.Find(i => i.Id== id)
中,输入变量i
进入lambda主体i.Id == id
(即作为匿名方法参数传递)。
还需要查看您正在使用的List<T>.Find
方法。它接受类型为T
的谓词,在您的情况下将是Predicate<Student>
。 Predicate是一个委托,表示定义一组条件并确定指定对象是否满足这些条件的方法。它具有以下签名:
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;
public StudentSearcher(int id)
{
_id = id;
}
public bool VerfyId(Student s)
{
return s.Id == _id;
}
}
现在您可以使用这个命名方法并为学生验证提供不同的
id
值:
var searcher = new StudentSearcher(id);
Student aStudent = students.Find(searcher.VerfyId);
但是为每个搜索创建这样的方法和类并不是很高效。这就是为什么我们有委托(和Lambda表达式)。您可以在需要的地方创建没有名称(匿名)的方法,而无需声明新的命名方法,编译器将为您生成常规的命名方法:
Student aStudent = students.Find(delegate(Student s) {
return s.Id == id;
});
同样的代码可以使用 lambda 语法编写 (省略 delegate 关键字,推断参数类型,使用 => 运算符分隔参数和方法体,同时省略 return 关键字):
Student aStudent = students.Find(s => s.Id == id)
这里的奇妙之处在于编译器会在幕后生成类,该类将具有谓词签名的方法,并且它还将具有用于捕获要搜索的
id
的字段。