5

Action<T>, Func<T> and Predicate<T>作为我的 WPF/MVVM 学习的一部分,我试图了解代表之间的差异。

我知道Action<T> and Func<T>两者都采用零到一个+参数,只Func<T>返回一个值而Action<T>不是。

至于Predicate<T>——我不知道。

因此,我提出了以下问题:

  1. 做什么Predicate<T>?(欢迎举例!)
  2. 如果没有Action<T>返回,那么使用它不是更简单吗?(或者任何其他类型,如果它是我们正在谈论的。)voidFunc<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);
}
}

注意:
我去掉了注释以避免超长的代码块。
完整的代码可以在这里找到。

任何帮助表示赞赏!谢谢!:)

PS:请不要指点我其他问题。我确实尝试过搜索,但找不到足够简单的东西让我理解。

4

6 回答 6

9

Predicate<T>是一个接受 aT并返回 a的委托bool
它完全等同于Func<T, bool>.

不同之处在于Predicate<T>在 .Net 2.0 中添加了,而所有Func<*>代表都是在 .Net 3.5 中添加的。(除了那些在.Net 4.0中添加的> 8个参数)

List<T>( FindAll(), TrueForAll(), 等)中的类 LINQ 方法采用Predicate<T>s。

要回答您的第二个问题,void不能用作通用参数。

于 2013-01-01T13:33:37.897 回答
1

谓词做什么?(欢迎举例!)

它必须返回boolean, 并在条件构造中使用。它等效于(但不可分配Func<T, bool>谓词主要用于 List 中的 FindAll 和 RemoveAll 等方法。

Action<T>对比Func<T,bool>

您不能将返回 void 的函数表示为Func<void, T>. 所以Action<T>是必需的。Void类型不能在泛型中使用。

于 2013-01-01T13:34:20.600 回答
1

谓词做什么?(欢迎举例!)

Predicate 是一个接受参数并返回 bool 的函数,例如x > 20

如果 Action 什么都不返回,那么使用 void 代替会更简单吗?(或者任何其他类型,如果它是我们正在谈论的 Func。)

Action 被定义为返回 void 的委托。在这里,人们可能会争论为什么会有两种代表,但这只是设计的结果。另一种方法是让Func返回Unit什么都不做。

于 2013-01-01T13:40:00.830 回答
1
Func<T,bool> and Predicate<T> 

倾向于同一个代表。但是 Predicate 是 Kindof 传统的,因为 Predicate 是一个委托类型,因为从一开始就没有 Func 或 Action。如果您会看到 Array ,List 等类的 FindAll/Find 方法,它们使用 Predicate.Predicates 仅返回 bool 但 Func 可以返回您指定的任何类型,因此 bool 也包含在内。

于 2013-01-01T13:49:53.363 回答
0

Predicate 是一个接受 T 并返回布尔值的委托,本质上它是一个过滤函数。或者这就是您将主要使用它的目的。

如果您使用 Linq 的 Where() 扩展方法,您将看到它接收一个 Predicate 委托作为参数,您也可以使用 Predicates 创建更复杂的过滤方法作为表达式,并动态组合多个 Predicate 委托与它们之间的 AND 或 OR 条件等等.

例如,我需要在 WPF 中构建一个报告页面,用户可以在其中动态选择多个参数来自定义报告页面的内容,在这种情况下,我为选定的过滤选项(日期时间间隔、布尔值、某些必须为包含在选定的字段等中),然后组合谓词并将它们编译成一个表达式,我后来用它来过滤我向用户展示的数据集合。


编辑:检查这个 -为什么 Func<T,bool> 而不是 Predicate<T>?

简而言之:编码指南声明不再使用谓词,而是使用 Func

于 2013-01-01T13:35:27.763 回答
-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.BeginInvokeDispatcher.BeginInvoke

Predicate真的只是一个特例Func<T, bool>,在所有Func和大多数Action代表都来之前介绍过。我怀疑如果我们已经拥有FuncAction以各种形式出现,Predicate就不会被引入......尽管它确实赋予了 , 的使用某种含义delegate,而FuncAction用于广泛不同的目的。

Predicate主要用于和List<T>之类的方法。FindAllRemoveAll

于 2013-01-01T13:39:05.937 回答