c#中的谓词是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1710301/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is a predicate in c#?
提问by Jebli
I am very new to using predicates and just learned how to write:
我对使用谓词很陌生,刚刚学会了如何编写:
Predicate<int> pre = delegate(int a){ a %2 == 0 };
What will the predicate return, and how is it useful when programming?
谓词将返回什么,它在编程时有何用处?
采纳答案by Dan Tao
Predicate<T>
is a functional construct providing a convenient way of basically testing if something is true of a given T
object.
Predicate<T>
是一个函数式构造,提供了一种基本测试给定T
对象是否为真的便捷方法。
For example suppose I have a class:
例如假设我有一个类:
class Person {
public string Name { get; set; }
public int Age { get; set; }
}
Now let's say I have a List<Person> people
and I want to know if there's anyone named Oscar in the list.
现在假设我有一个List<Person> people
,我想知道列表中是否有人叫 Oscar。
Withoutusing a Predicate<Person>
(or Linq, or any of that fancy stuff), I could always accomplish this by doing the following:
不使用Predicate<Person>
(或 Linq,或任何其他花哨的东西),我总是可以通过执行以下操作来完成此操作:
Person oscar = null;
foreach (Person person in people) {
if (person.Name == "Oscar") {
oscar = person;
break;
}
}
if (oscar != null) {
// Oscar exists!
}
This is fine, but then let's say I want to check if there's a person named "Ruth"? Or a person whose age is 17?
这很好,但是假设我想检查是否有一个名为“Ruth”的人?还是一个 17 岁的人?
Using a Predicate<Person>
, I can find these things using a LOT less code:
使用 a 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);
Notice I said a lot less code, not a lot faster. A common misconception developers have is that if something takes one line, it must perform better than something that takes ten lines. But behind the scenes, the Find
method, which takes a Predicate<T>
, is just enumerating after all. The same is true for a lot of Linq's functionality.
注意我说的代码少了很多,并不是说快了很多。开发人员的一个常见误解是,如果某样东西只需要一行,它的性能肯定比需要 10 行的东西更好。但在幕后,Find
采用 a的方法Predicate<T>
毕竟只是枚举。Linq 的许多功能也是如此。
So let's take a look at the specific code in your question:
那么我们来看看你问题中的具体代码:
Predicate<int> pre = delegate(int a){ return a % 2 == 0; };
Here we have a Predicate<int> pre
that takes an int a
and returns a % 2 == 0
. This is essentially testing for an even number. What that means is:
这里我们有一个Predicate<int> pre
接受 anint a
并返回a % 2 == 0
。这本质上是测试偶数。这意味着:
pre(1) == false;
pre(2) == true;
And so on. This also means, if you have a List<int> ints
and you want to find the first even number, you can just do this:
等等。这也意味着,如果你有 aList<int> ints
并且你想找到第一个偶数,你可以这样做:
int firstEven = ints.Find(pre);
Of course, as with any other type that you can use in code, it's a good idea to give your variables descriptive names; so I would advise changing the above pre
to something like evenFinder
or isEven
-- something along those lines. Then the above code is a lot clearer:
当然,与您可以在代码中使用的任何其他类型一样,为您的变量提供描述性名称是个好主意;所以我建议将上述内容更改为pre
类似evenFinder
或isEven
- 类似的内容。那么上面的代码就清晰了很多:
int firstEven = ints.Find(evenFinder);
回答by Reed Copsey
The Predicate will always return a boolean, by definition.
根据定义,谓词将始终返回一个布尔值。
Predicate<T>
is basically identical to Func<T,bool>
.
Predicate<T>
与 基本相同Func<T,bool>
。
Predicates are very useful in programming. They are often used to allow you to provide logic at runtime, that can be as simple or as complicated as necessary.
谓词在编程中非常有用。它们通常用于允许您在运行时提供逻辑,可以根据需要简单或复杂。
For example, WPF uses a Predicate<T>
as input for Filtering of a ListView's ICollectionView. This lets you write logic that can return a boolean determining whether a specific element should be included in the final view. The logic can be very simple (just return a boolean on the object) or very complex, all up to you.
例如,WPF 使用 aPredicate<T>
作为过滤 ListView 的 ICollectionView 的输入。这使您可以编写可以返回布尔值的逻辑,以确定是否应将特定元素包含在最终视图中。逻辑可以非常简单(只需在对象上返回一个布尔值)或非常复杂,一切由您决定。
回答by osij2is
In C# Predicates are simply delegates that return booleans. They're useful (in my experience) when you're searching through a collection of objects and want something specific.
在 C# 中,谓词只是返回布尔值的委托。当您搜索对象集合并想要特定的东西时,它们很有用(根据我的经验)。
I've recently run into them in using 3rd party web controls (like treeviews) so when I need to find a node within a tree, I use the .Find() method and pass a predicate that will return the specific node I'm looking for. In your example, if 'a' mod 2 is 0, the delegate will return true. Granted, when I'm looking for a node in a treeview, I compare it's name, text and value properties for a match. When the delegate finds a match, it returns the specific node I was looking for.
我最近在使用 3rd 方 Web 控件(如树视图)时遇到了它们,所以当我需要在树中找到一个节点时,我使用 .Find() 方法并传递一个谓词,该谓词将返回我的特定节点寻找。在您的示例中,如果 'a' mod 2 为 0,则委托将返回 true。当然,当我在树视图中查找节点时,我会比较它的名称、文本和值属性以进行匹配。当委托找到匹配项时,它会返回我正在寻找的特定节点。
回答by Brahim Boulkriat
The following code can help you to understand some real world use of predicates (Combined with named iterators).
以下代码可以帮助您了解谓词的一些实际使用(结合命名迭代器)。
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;
}
}
}