我很新的使用谓词和刚学会写:什么是C#中的谓词?
Predicate<int> pre = delegate(int a){ a %2 == 0 };
会有什么谓语回报,它是如何有用的编程是什么时候?
我很新的使用谓词和刚学会写:什么是C#中的谓词?
Predicate<int> pre = delegate(int a){ a %2 == 0 };
会有什么谓语回报,它是如何有用的编程是什么时候?
Predicate<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!
}
这是好的,但后来我们说,我想检查是否有名为“露丝”的人?还是17岁的人?
使用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);
通知我说了很多更少的代码,不是很多更快。开发人员常见的误解是,如果某件事情需要一条线,那么它的表现要比需要十条线的事情要好。但在幕后,采用Predicate<T>
的Find
方法毕竟只是枚举。 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
或isEven
之类的东西 - 沿着这些线。然后,上面的代码是一个更加清晰:
int firstEven = ints.Find(evenFinder);
+1!到目前为止,页面上最清晰的答案。 – 2009-11-10 19:15:50
+1:写得很好。我只想添加单行表单MSDN:“表示定义一组标准并确定指定对象是否符合这些标准的方法” – 2009-11-10 19:26:03
令人惊叹。也解答了这个问题。 – 2009-11-10 19:27:27
根据定义,Predicate将始终返回一个布尔值。
Predicate<T>
基本上与Func<T,bool>
相同。
谓词在编程中非常有用。它们通常用于允许您在运行时提供逻辑,可以根据需要尽可能简单或复杂。
例如,WPF使用Predicate<T>
作为输入来过滤ListView的ICollectionView。这使您可以编写可以返回布尔值的逻辑,以确定是否应在最终视图中包含特定元素。逻辑可以非常简单(只需在对象上返回一个布尔值)或非常复杂,全部由您决定。
只是可惜他们不是:) – leppie 2009-11-10 18:55:28
代表在编程中很有用。坦率地说,我发现Predicate这个名字非常无益,因为这个问题明显证明了这一点。如果你真的想描述一个谓词,你会命名它Filter
不是什么? [15个字符] – 2009-11-10 19:00:21
在C#中谓词只是代表返回布尔值的代表。当你搜索对象集合并想要特定的东西时,它们是有用的(以我的经验)。
我最近在使用第三方网页控件(如treeviews)时遇到了他们,所以当我需要在树中查找节点时,我使用.Find()方法并传递一个将返回特定节点我正在寻找。在你的例子中,如果'a'mod 2是0,委托将返回true。当然,当我在树形视图中查找节点时,我会比较它的名称,文本和值属性以进行匹配。当委托人发现匹配时,它返回我正在寻找的特定节点。
下面的代码可以帮助你了解一些现实世界中使用的谓词(名为迭代器相结合)。
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;
}
}
}
或者,您可以不用foreach/yield循环来“返回persons.FindAll(isOld);”。 – 2017-08-13 02:14:34
这里是我的博士辣椒,谓词和安全功能的文章:http://blogs.msdn.com/ericlippert/archive/2008/08/19/tasty-beverages.aspx – 2009-11-10 21:30:21
@ 0A0D:我觉得如果问题不是特定于该版本,那么标记问题“.net-2.0”是一个糟糕的主意。只需标记“.net”。 – 2010-08-28 00:04:11
@John:同意。它原来有2.0,所以我只是将.net和2.0合并到.net-2.0中。 – 2010-08-28 00:19:52