c#中的谓词是什么?

时间:2009-11-10 18:52:34

标签: c# .net vb.net predicate

我对使用谓词非常陌生,只是学习了如何编写:

Predicate<int> pre = delegate(int a){ a %2 == 0 };

谓词将返回什么,以及编程时它如何有用?

4 个答案:

答案 0 :(得分:443)

Predicate<T>是一个功能构造,提供了一种方便的方法来基本测试某个给定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);

注意我说了很多更少的代码,而不是很多更快的。开发人员常见的误解是,如果某些东西需要一行,那么它必须比需要十行的东西表现更好。但在幕后,采用Find的{​​{1}}方法毕竟只是枚举。 Linq的许多功能也是如此。

让我们来看看你问题中的具体代码:

Predicate<T>

我们有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); 更改为类似preevenFinder的内容。然后上面的代码更加清晰:

isEven

答案 1 :(得分:43)

根据定义,谓词将始终返回布尔值。

Predicate<T>Func<T,bool>基本相同。

谓词在编程中非常有用。它们通常用于允许您在运行时提供逻辑,可以根据需要简单或复杂。

例如,WPF使用Predicate<T>作为过滤ListView的ICollectionView的输入。这使您可以编写可返回布尔值的逻辑,以确定特定元素是否应包含在最终视图中。逻辑可以非常简单(只是在对象上返回一个布尔值)或非常复杂,全部取决于你。

答案 2 :(得分:16)

以下代码可以帮助您理解谓词的一些实际使用(与命名迭代器结合使用)。

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

答案 3 :(得分:14)

在C#中,谓词只是返回布尔值的委托。当您搜索对象集合并想要特定的东西时,它们(根据我的经验)是有用的。

我最近遇到了使用第三方Web控件(比如树视图)的问题,所以当我需要在树中查找节点时,我使用.Find()方法并传递一个谓词,该谓词将返回特定节点我在找。在您的示例中,如果'a'mod 2为0,则委托将返回true。当然,当我在树视图中寻找节点时,我会比较匹配的名称,文本和值属性。当委托找到匹配项时,它返回我正在寻找的特定节点。