Predicate<T>
是一个函数式构造,提供了一种方便的方法来基本测试给定的某件事是否正确T
object.
例如假设我有一堂课:
class Person {
public string Name { get; set; }
public int Age { get; set; }
}
现在假设我有一个List<Person> people
我想知道名单上是否有叫奥斯卡的人。
Without用一个Predicate<Person>
(或者 Linq,或者任何那些奇特的东西),我总是可以通过执行以下操作来完成此任务:
Person oscar = null;
foreach (Person person in people) {
if (person.Name == "Oscar") {
oscar = person;
break;
}
}
if (oscar != null) {
// Oscar exists!
}
这很好,但是假设我想检查是否有一个名为“Ruth”的人?还是17岁的人?
Using a Predicate<Person>
,我可以使用更少的代码找到这些东西:
Predicate<Person> oscarFinder = (Person p) => { return p.Name == "Oscar"; };
Predicate<Person> ruthFinder = (Person p) => { return p.Name == "Ruth"; };
Predicate<Person> seventeenYearOldFinder = (Person p) => { return p.Age == 17; };
Person oscar = people.Find(oscarFinder);
Person ruth = people.Find(ruthFinder);
Person seventeenYearOld = people.Find(seventeenYearOldFinder);
注意我说了很多更少的代码, 不是很多faster。开发人员的一个常见误解是,如果某个东西只需要一行,那么它的性能一定比需要十行的东西要好。但在幕后,Find
方法,该方法需要一个Predicate<T>
,毕竟只是列举而已。 Linq 的许多功能也是如此。
那么我们来看看你问题中的具体代码:
Predicate<int> pre = delegate(int a){ return a % 2 == 0; };
在这里我们有一个Predicate<int> pre
这需要一个int a
并返回a % 2 == 0
。这本质上是测试偶数。这意味着:
pre(1) == false;
pre(2) == true;
等等。这也意味着,如果您有List<int> ints
如果你想找到第一个偶数,你可以这样做:
int firstEven = ints.Find(pre);
当然,与您可以在代码中使用的任何其他类型一样,最好为变量提供描述性名称;所以我建议改变上面的内容pre
类似的东西evenFinder
or isEven
——类似的事情。那么上面的代码就清晰很多了:
int firstEven = ints.Find(evenFinder);