c#中的谓词是什么?
我对使用谓词非常陌生,刚刚学会了如何编写:c#中的谓词是什么?,c#,.net,vb.net,predicate,C#,.net,Vb.net,Predicate,我对使用谓词非常陌生,刚刚学会了如何编写: Predicate<int> pre = delegate(int a){ a %2 == 0 }; 谓词pre=delegate(inta){a%2==0}; 谓词将返回什么,以及它在编程时如何有用?根据定义,谓词将始终返回布尔值 基本上与Func相同 谓词在编程中非常有用。它们通常用于允许您在运行时提供逻辑,可以是简单的,也可以是复杂的 例如,WPF使用谓词作为ListView的ICollectionView的过滤输入。这使您可以编
Predicate<int> pre = delegate(int a){ a %2 == 0 };
谓词pre=delegate(inta){a%2==0};
谓词将返回什么,以及它在编程时如何有用?根据定义,谓词将始终返回布尔值 基本上与
Func
相同
谓词在编程中非常有用。它们通常用于允许您在运行时提供逻辑,可以是简单的,也可以是复杂的
例如,WPF使用谓词
作为ListView的ICollectionView的过滤输入。这使您可以编写逻辑,该逻辑可以返回一个布尔值,以确定特定元素是否应包含在最终视图中。逻辑可以非常简单(只需在对象上返回布尔值)也可以非常复杂,这取决于您。在C#中,谓词只是返回布尔值的委托。在我的经验中,当你在一个对象集合中搜索并想要一些特定的东西时,它们很有用
我最近在使用第三方web控件(如TreeView)时遇到了它们,因此当我需要在树中查找节点时,我使用.find()方法并传递一个谓词,该谓词将返回我正在查找的特定节点。在您的示例中,如果'a'mod 2为0,则委托将返回true。当然,当我在树状视图中查找节点时,我会比较它的名称、文本和值属性以获得匹配。当委托找到匹配项时,它将返回我要查找的特定节点。谓词是一种函数构造,它提供了一种方便的方法,基本上可以测试给定的T
对象是否正确
例如,假设我有一个类:
class Person {
public string Name { get; set; }
public int Age { get; set; }
}
现在让我们假设我有一个人名单
,我想知道名单上是否有人叫奥斯卡
如果不使用谓词
(或Linq,或任何类似的东西),我总是可以通过执行以下操作来实现这一点:
Person oscar = null;
foreach (Person person in people) {
if (person.Name == "Oscar") {
oscar = person;
break;
}
}
if (oscar != null) {
// Oscar exists!
}
这很好,但假设我想看看是否有一个叫“露丝”的人?还是一个17岁的人
使用谓词
,我可以用更少的代码找到这些东西:
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);
这里我们有一个谓词pre
,它接受int a
并返回a%2==0
。这本质上是对偶数的测试。这意味着:
pre(1) == false;
pre(2) == true;
等等。这也意味着,如果您有一个列表ints
,并且您想要找到第一个偶数,您可以这样做:
int firstEven = ints.Find(pre);
当然,与您可以在代码中使用的任何其他类型一样,最好为变量指定描述性名称;因此,我建议将上述pre
更改为类似于evenFinder
或isEven
——类似于这些内容的内容。那么上面的代码就更清楚了:
int firstEven = ints.Find(evenFinder);
下面的代码可以帮助您了解谓词(与命名迭代器结合使用)的一些实际用法
名称空间谓词
{
班主任
{
公共整数{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
foreach(OlderThan(18)中的人员)
{
控制台写入线(人、年龄);
}
}
静态IEnumerable OlderThan(整数年龄)
{
谓词isOld=x=>x.Age>Age;
Person[]persons={新人{Age=10}、新人{Age=20}、新人{Age=19};
foreach(一人一人)
如果(isOld(person))放弃返回人;
}
}
}
学员在编程中很有用。坦率地说,我发现名称谓词毫无用处,正如这个问题清楚地证明的那样。如果你真的想描述一个谓词是什么,你可以将它命名为Filter。@Ed:我想他是在暗示,遗憾的是它们不仅仅是function,它们不是同一类型,因此彼此之间不能转换。将它命名为谓词对我来说非常有意义……它是一个用于分支逻辑的布尔值函数……+1!到目前为止,这是这一页上最清楚的答案。我只想添加一行表单MSDN:“表示定义一组条件并确定指定对象是否满足这些条件的方法”。这个问题也很难回答。评论不错!你在2009年回答了这个问题,到2019年它仍然有用。因为有像你这样的人,世界仍然美丽。很好的解释,谢谢你的回答。或者,你可以“return persons.FindAll(isOld);”而不是foreach/yield循环。
int firstEven = ints.Find(evenFinder);
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;
}
}
}