Action,Func和Predicate委托 – C#
我试图理解Action, Func and Predicate
委托之间的差异,作为我的WPF / MVVM学习的一部分。
我知道Action and Func
都采用零到一个+参数,只有Func
返回一个值,而Action
则没有。
至于Predicate
– 我不知道。
因此,我提出了以下问题:
-
Predicate
做什么? (欢迎举例!) - 如果
Action
什么都不返回,那么仅使用void
会不会更简单? (或任何其他类型,如果它是我们正在讨论的Func
。)
我希望你在问题中避免使用LINQ / List示例。
我已经看过那些但是它们只是让它变得更加混乱,因为让我对这些代表“感兴趣”的代码与它无关(我想!)。
因此,我想使用我熟悉的代码来获得我的答案。
这里是:
public class RelayCommand : ICommand { readonly Action _execute; readonly Predicate _canExecute; public RelayCommand(Action execute) : this(execute, null) { } public RelayCommand(Action execute, Predicate 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); } }
注意:
我拿出评论来避免超长代码块。
完整的代码可以在这里找到。
任何帮助表示赞赏! 谢谢! 🙂
PS:请不要指我其他问题。 我确实尝试搜索,但我找不到任何简单的东西让我理解。
Predicate
是一个代表,它接受一个T
并返回一个bool
。
它完全等同于Func
。
区别在于Predicate
是在.Net 2.0中添加的,而所有Func<*>
代表都是在.Net 3.5中添加的。 (除了具有> 8个参数的那些,在.Net 4.0中添加)
List
( FindAll()
, TrueForAll()
等中类似LINQ的方法采用Predicate
。
要回答第二个问题, void
不能用作通用参数。
Predicate做什么? (欢迎举例!)
谓词是一个函数,它接受一个参数并返回bool,例如x > 20
如果Action没有返回任何内容,那么仅使用void会不会更简单? (或任何其他类型,如果它是我们正在讨论的Func。)
Action被定义为返回void的委托。 在这里,人们可能会争论为什么有两种代表,但这只是设计的结果。 另一种方法是使Func
返回不执行任何操作的Unit
。
Predicate做什么? (欢迎举例!)
它必须返回boolean
,并在条件结构中使用。 它与Func
等效( 但不可分配 )。 对于像FindAll和RemoveAll这样的方法,谓词主要用在List中。
Action
vs Func
你不能表示一个函数返回void作为Func
。 所以Action
是必需的。 Void
类型不能用于generics 。
Func and Predicate
往往是同一个代表。 但谓词是传统的,因为谓词是一个委托类型,从一开始就没有Func或Action。 如果您将看到像Array,List这样的类的FindAll / Find方法,他们使用Predicate.Predicates只返回bool但Func可以返回您指定的任何类型,因此bool也会出现。
Predicate是一个委托,它接受一个T并返回一个布尔值,本质上它是一个过滤函数。 或者这就是你将主要使用它。
如果您使用Linq的Where()扩展方法,您将看到它接收Predicate委托作为参数,您也可以使用Predicates创建更复杂的过滤方法作为表达式,并动态组合多个Predicate委托与它们之间的AND或OR条件等等。
例如,我需要在WPF中构建一个Report页面,用户可以动态选择多个参数来自定义Report页面的内容,在这种情况下,我为所选的过滤选项创建了Predicates(日期时间间隔,布尔值,必须的某些字符串)包含在选定的字段等中)然后组合谓词并将它们编译成一个表达式,我后来用它来过滤我向用户显示的数据集合。
编辑:检查这个 – 为什么Func
简而言之:编码指南声明不再使用Predicates而是使用Func
Func和Action之间的区别仅在于您是希望委托返回值(使用Func)还是不使用(使用Action)。
Func可能是LINQ中最常用的 – 例如在投影中:
list.Select(x => x.SomeProperty)
或过滤:
list.Where(x => x.SomeValue == someOtherValue)
或关键选择:
list.Join(otherList, x => x.FirstKey, y => y.SecondKey, ...)
Action
更常用于List
类的东西。
ForEach
:为列表中的每个项执行给定的操作。
我使用它比Func
更少,尽管我有时会使用无参数版本来控制Control.BeginInvoke
和Dispatcher.BeginInvoke
。
Predicate
只是一个特殊的套装Func
真的,在所有Func
和大多数Action
代表出现之前引入。 我怀疑,如果我们已经有各种伪装的Func
和Action
,那么Predicate
就不会被引入……虽然它确实赋予delegate
使用一定的意义,而Func
和Action
则被广泛使用目的。
Predicate
主要用于List
用于FindAll
和RemoveAll
等方法。