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;
        }
    }
}