我正在尝试理解Action<T>, Func<T> and Predicate<T>
代表之间的差异,这是我的WPF / MVVM学习的一部分。
我知道Action<T> and Func<T>
只有0到1 +参数,只有Func<T>
会返回一个值而Action<T>
则没有。
关于Predicate<T>
- 我不知道。
因此,我提出了以下问题:
Predicate<T>
做什么? (欢迎举例!)Action<T>
返回没有,那么仅使用void
会不会更简单? (或任何其他类型,如果我们正在讨论Func<T>
。)我希望您在问题中避免使用LINQ / List示例 我已经看过那些但是它们只是让它变得更加混乱,因为让我对这些代表感兴趣的代码与它无关(我想!)。 因此,我想使用我熟悉的代码来获得我的答案。
这是:
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);
}
}
注意:
我拿出评论来避免超长的代码块
完整代码可以找到HERE。
任何帮助表示赞赏!谢谢! :)
P.S:请不要指我其他问题。我确实尝试过搜索,但找不到任何简单的东西让我理解。答案 0 :(得分:9)
Predicate<T>
是一个代理人,他需要T
并返回bool
。
它完全等同于Func<T, bool>
。
不同之处在于。{2.0}中添加了Predicate<T>
,而在.Net 3.5中添加了所有Func<*>
代理。 (除了带有&gt; 8参数的那些,在.Net 4.0中添加)
List<T>
(FindAll()
,TrueForAll()
等)中类似LINQ的方法采用Predicate<T>
s。
要回答第二个问题,void
不能用作通用参数。
答案 1 :(得分:1)
Predicate做什么? (欢迎举例!)
必须返回boolean
,并在条件结构中使用。它等同于{but not assignable)到Func<T, bool>
。 Predicate is mostly used in List for methods like FindAll and RemoveAll.
Action<T>
vs Func<T,bool>
您无法将函数返回void Func<void, T>
。因此Action<T>
是必需的。 generics无法使用Void
类型。
答案 2 :(得分:1)
Predicate做什么? (欢迎举例!)
谓词是一个接受参数并返回bool的函数,例如x > 20
如果Action没有返回任何内容,那么仅使用void会不会更简单? (或者任何其他类型,如果我们正在谈论的是Func。)
Action被定义为返回void的委托。在这里,人们可能会争论为什么会有两种代表,但这只是设计的结果。另一种方法是让Func
返回无效的Unit
。
答案 3 :(得分:1)
Func<T,bool> and Predicate<T>
倾向于同一个代表。 但谓词是传统的,因为谓词是代表类型 从没有Func或Action开始。 如果您将看到像Array,List这样的类的FindAll / Find方法 他们使用Predicate.Predicates只返回bool但Func可以返回你指定的任何类型,所以bool也会出现。
答案 4 :(得分:0)
Predicate是一个委托,它接受一个T并返回一个布尔值,实质上它是一个过滤函数。或者这就是你将主要使用它。
如果使用Linq的Where()扩展方法,您将看到它接收Predicate委托作为参数,您也可以使用Predicates创建更复杂的过滤方法作为表达式,并动态组合多个Predicate委托与它们之间的AND或OR条件等等。
例如,我需要在WPF中构建一个Report页面,用户可以动态选择多个参数来自定义Report页面的内容,在这种情况下,我为所选的过滤选项创建了Predicates(日期时间间隔,布尔值,某些字符串)必须包含在选定的字段等中)然后组合谓词并将它们编译成一个表达式,我后来用它来过滤我向用户显示的数据集合。
编辑:检查一下 - Why Func<T,bool> instead of Predicate<T>?
简而言之:编码指南声明不再使用Predicates而是使用Func
答案 5 :(得分:-1)
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<T>
等内容。
ForEach
:对列表中的每个项目执行给定的操作。
我使用此频率的频率低于Func
,但有时我会使用无参数版本来处理Control.BeginInvoke
和Dispatcher.BeginInvoke
等内容。
Predicate
只是一个特殊的Func<T, bool>
,在所有Func
和大多数Action
代表出现之前就已经介绍过了。我怀疑,如果我们已经有Func
和Action
各种伪装,Predicate
就不会被引入......尽管它确实赋予了使用delegate
,而Func
和Action
用于广泛不同的目的。
Predicate
主要用于List<T>
,用于FindAll
和RemoveAll
等方法。