wpf Action、Func 和 Predicate 委托 - C#
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14110889/
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
Action, Func and Predicate delegates - C#
提问by Asaf
I'm trying to understand the differences between the Action<T>, Func<T> and Predicate<T>delegates as part of my WPF/MVVM learning.
Action<T>, Func<T> and Predicate<T>作为 WPF/MVVM 学习的一部分,我试图了解代表之间的差异。
I know Action<T> and Func<T>both take zero to one+ parameters, only Func<T>returns a value while Action<T>don't.
我知道Action<T> and Func<T>两者都采用零到一个以上的参数,只Func<T>返回一个值而不返回一个值Action<T>。
As for Predicate<T>- I have no idea.
至于Predicate<T>- 我不知道。
Therefore, I came up with this following questions:
因此,我想出了以下问题:
- What does
Predicate<T>do? (Examples welcomed!) - If
Action<T>returns nothing, wouldn't it be simpler to just usevoidinstead? (Or any other type if it'sFunc<T>we're talking about.)
- 有什么作用
Predicate<T>?(欢迎举例!) - 如果什么都不
Action<T>返回,那么使用它不是更简单吗?(或者任何其他类型,如果它是我们正在谈论的。)voidFunc<T>
I'd like you to avoid LINQ/List examples in your questions.
I've seen those already but they just make it more confusing as the code that got me 'interested' in these delegates have nothing to do with it (I think!).
Therefore, I'd like to use a code I'm familiar with to get my answer.
我希望您避免在问题中使用 LINQ/List 示例。
我已经看过那些,但它们只会让我更加困惑,因为让我对这些代表“感兴趣”的代码与它无关(我认为!)。
因此,我想使用我熟悉的代码来获得答案。
Here it is:
这里是:
public class RelayCommand : ICommand
{
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
[DebuggerStepThrough]
public bool CanExecute(object parameters)
{
return _canExecute == null ? true : _canExecute(parameters);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameters)
{
_execute(parameters);
}
}
Note:
I took out the comments to avoid super-long block of code.
The full code can be found HERE.
注意:
我把注释去掉是为了避免超长的代码块。
完整代码可以在这里找到。
Any help is appreciated! Thanks! :)
任何帮助表示赞赏!谢谢!:)
P.S: Please don't point me to other questions. I did try to search but I couldn't find anything simple enough for me to understand.
PS:请不要指向我其他问题。我确实尝试过搜索,但找不到任何足以让我理解的简单内容。
回答by SLaks
Predicate<T>is a delegate that takes a Tand returns a bool.
It's completely equivalent to Func<T, bool>.
Predicate<T>是一个接受 aT并返回 a的委托bool。
它完全等同于Func<T, bool>.
The difference is that Predicate<T>was added in .Net 2.0, whereas all of the Func<*>delegates were added in .Net 3.5. (except the ones with >8 parameters, which were added in .Net 4.0)
不同之处在于它Predicate<T>是在 .Net 2.0 中添加的,而所有Func<*>委托都是在 .Net 3.5 中添加的。(除了那些在 .Net 4.0 中添加的 >8 个参数的参数)
The LINQ-like methods in List<T>(FindAll(), TrueForAll(), etc) take Predicate<T>s.
的LINQ状的方法List<T>(FindAll(),TrueForAll()等)取Predicate<T>秒。
To answer your second question, voidcannot be used as a generic parameter.
回答你的第二个问题,void不能用作通用参数。
回答by Lukasz Madon
What does Predicate do? (Examples welcomed!)
谓词有什么作用?(欢迎举例!)
Predicate is a function that takes an argument and returns bool e.g x > 20
Predicate 是一个接受参数并返回 bool 的函数,例如 x > 20
If Action returns nothing, wouldn't it be simpler to just use void instead? (Or any other type if it's Func we're talking about.)
如果 Action 什么都不返回,那么使用 void 不是更简单吗?(或者任何其他类型,如果它是我们正在谈论的 Func。)
Action is defined as delegate that returns void. Here one may argue why there are two kind of delegates, but simply that's the outcome of the design. Another approach is to have Functhat returns Unitthat does nothing.
Action 被定义为返回 void 的委托。这里有人可能会争论为什么有两种代表,但这就是设计的结果。另一种方法是Func让返回Unit什么都不做。
回答by yo chauhan
Func<T,bool> and Predicate<T>
tends to the same delegate. But Predicate is Kindof traditional because Predicate was a delegate Type since from beginning when there was no Func or Action. If you will see FindAll/Find method of classes like Array ,List they use Predicate.Predicates return only bool but Func can return any type you specify so bool also comes in that.
倾向于同一个代表。但是 Predicate 是 Kindof 传统的,因为 Predicate 从一开始就没有 Func 或 Action 就是一个委托类型。如果你会看到像 Array ,List 这样的类的 FindAll/Find 方法,它们使用 Predicate.Predicates 只返回 bool 但 Func 可以返回你指定的任何类型,所以 bool 也包含在内。
回答by Tilak
What does Predicate do? (Examples welcomed!)
谓词有什么作用?(欢迎举例!)
It must return boolean, and used in conditional constructs. It is equivalent (but not assignable) to Func<T, bool>. Predicate is mostly used in List for methods like FindAll and RemoveAll.
它必须返回boolean,并用于条件构造。它等效于(但不可分配)到Func<T, bool>. 谓词主要在 List 中用于 FindAll 和 RemoveAll 等方法。
Action<T>vs Func<T,bool>
Action<T>对比 Func<T,bool>
You cant represent a function returning void as Func<void, T>. So Action<T>is required. Voidtype cannot be used in generics.
您不能将返回 void 的函数表示为Func<void, T>。所以Action<T>是必需的。Void类型不能用于泛型。
回答by dutzu
A Predicate is a delegate that takes a T and returns a boolean, in essence it's a filtering function. Or that is what you will use it for mostly.
Predicate 是一个接受 T 并返回一个布尔值的委托,本质上它是一个过滤函数。或者这就是您将主要使用它的目的。
If you use Linq's Where() extension method you will see it receives a Predicate delegate as a parameter, also you can use Predicates to create more intricate filtering methods as Expressions and dynamically combine multiple Predicate delegates with AND or OR conditions between them and so forth.
如果您使用 Linq 的 Where() 扩展方法,您将看到它接收一个 Predicate 委托作为参数,您也可以使用 Predicates 创建更复杂的过滤方法作为表达式,并动态组合多个 Predicate 委托与它们之间的 AND 或 OR 条件等等.
For example i had a requirement to build a Report page in WPF where the user could dynamically select multiple parameters to customize the Report page's content, and in that case i created Predicates for selected filtering options (datetime intervals, booleans, certain strings that must be contained in selected fields etc.) and then combined the predicates and compiled them into an expression that i later used to filter the collection of data i showed the user.
例如,我需要在 WPF 中构建一个报告页面,用户可以在其中动态选择多个参数来自定义报告页面的内容,在这种情况下,我为选定的过滤选项(日期时间间隔、布尔值、某些必须是包含在选定的字段等中),然后组合谓词并将它们编译成一个表达式,我后来用它来过滤我向用户展示的数据集合。
EDIT: Check this - Why Func<T,bool> instead of Predicate<T>?
编辑:检查这个 -为什么 Func<T,bool> 而不是 Predicate<T>?
in short : coding guidelines state to not use Predicates anymore and use Func instead
简而言之:编码指南规定不再使用谓词,而是使用 Func
回答by Azzy
The difference between Func and Action is simply whether you want the delegate to return a value (use Func) or doesn't (use Action).
Func 和 Action 之间的区别仅在于您希望委托返回值(使用 Func)还是不返回值(使用 Action)。
Func is probably most commonly used in LINQ - for example in projections:
Func 可能最常用于 LINQ - 例如在投影中:
list.Select(x => x.SomeProperty)
or filtering:
或过滤:
list.Where(x => x.SomeValue == someOtherValue)
or key selection:
或键选择:
list.Join(otherList, x => x.FirstKey, y => y.SecondKey, ...)
Actionis more commonly used for things like List<T>.
Action更常用于诸如List<T>.
ForEach: execute the given action for each item in the list.
ForEach: 对列表中的每个项目执行给定的操作。
I use this less often than Func, although I do sometimes use the parameterless version for things like Control.BeginInvokeand Dispatcher.BeginInvoke.
我使用它的频率低于Func,尽管我有时会使用无参数版本来处理Control.BeginInvoke和Dispatcher.BeginInvoke。
Predicateis just a special cased Func<T, bool>really, introduced before all of the Funcand most of the Actiondelegates came along. I suspect that if we'd already had Funcand Actionin their various guises, Predicatewouldn't have been introduced... although it does impart a certain meaning to the use of the delegate, whereas Funcand Actionare used for widely disparate purposes.
PredicateFunc<T, bool>真的只是一个特例,在所有代表Func和大多数Action代表出现之前介绍。我怀疑,如果我们已经拥有Func并且Action以它们的各种形式出现,Predicate就不会被引入......尽管它确实赋予 的使用某种意义delegate,而Func和Action用于广泛不同的目的。
Predicateis mostly used in List<T>for methods like FindAlland RemoveAll.
Predicate主要用于List<T>像FindAll和这样的方法RemoveAll。

