什么是C#中的谓词?
我对使用谓词很陌生,刚学会如何写:
Predicate<int> pre = delegate(int a){ a %2 == 0 };
谓词将返回什么,编程时它有什么用处?
Predicate<T>
是一个函数构造,提供了一个基本testing是否对于给定的T
对象是真实的方便的方法。
例如,假设我有一个类:
class Person { public string Name { get; set; } public int Age { get; set; } }
现在让我们说我有一个List<Person> people
,我想知道是否有人名单上的奥斯卡。
如果不使用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岁的人?
使用Predicate<Person>
,我可以用很less的代码find这些东西:
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);
注意我说的代码less得多 , 速度不是很快 。 开发人员常见的误解是,如果某件事情需要一条线,那么它的performance要比十条线要好。 但在幕后,使用Predicate<T>
的Find
方法毕竟只是枚举。 很多Linq的function也是如此。
所以让我们看看你的问题中的具体代码:
Predicate<int> pre = delegate(int a){ return a % 2 == 0; };
这里我们有一个Predicate<int> pre
,它接受一个int a
并返回a % 2 == 0
。 这本质上是testing一个偶数。 这意味着什么:
pre(1) == false; pre(2) == true;
等等。 这也意味着,如果你有一个List<int> ints
,你想find第一个偶数,你可以这样做:
int firstEven = ints.Find(pre);
当然,和其他你可以在代码中使用的types一样,给你的variables描述性的名字是个好主意。 所以我build议把上面的pre
evenFinder
或isEven
这样的东西。 那么上面的代码就更清晰了:
int firstEven = ints.Find(evenFinder);
谓词总是会返回一个布尔值,按照定义。
Predicate<T>
与Func<T,bool>
基本相同。
谓词在编程中非常有用。 它们通常用于允许您在运行时提供逻辑,可以根据需要简单或复杂。
例如,WPF使用Predicate<T>
作为ListView的ICollectionView的filter的input。 这使您可以编写可以返回布尔值的逻辑,确定是否在最终视图中包含特定的元素。 逻辑可以非常简单(只要返回一个对象的布尔值)或非常复杂,一切由您决定。
下面的代码可以帮助你理解谓词的一些真实世界的使用(与命名迭代器结合)。
namespace Predicate { class Person { public int Age { get; set; } } class Program { static void Main(string[] args) { foreach (Person person in OlderThan(18)) { Console.WriteLine(person.Age); } } static IEnumerable<Person> OlderThan(int age) { Predicate<Person> isOld = x => x.Age > age; Person[] persons = { new Person { Age = 10 }, new Person { Age = 20 }, new Person { Age = 19 } }; foreach (Person person in persons) if (isOld(person)) yield return person; } } }
在C#中谓词只是代表返回布尔值。 当您search对象集合并想要特定的东西时,它们是有用的(以我的经验)。
我最近碰到使用第三方Web控件(比如treeviews)的时候,所以当我需要在树中find一个节点时,我使用.Find()方法并传递一个谓词来返回特定的节点。寻找。 在你的例子中,如果'a'mod 2是0,委托将返回true。 当然,当我在树形视图中查找节点时,我会比较它的名称,文本和值属性。 当代表发现匹配时,它返回我正在寻找的特定节点。