协慌网

登录 贡献 社区

Func vs.Action vs.Predicate

借助真实的示例及其用法,有人可以帮助我理解以下内容:

  1. 什么时候需要Func<T, ..>委托?
  2. 我们什么时候需要一个Action<T>委托?
  3. 什么时候需要Predicate<T>委托?

答案

FuncAction之间的区别只是您是否希望委托返回一个值(使用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 ... 尽管它确实为委托的使用赋予了一定意义,而FuncAction却被广泛使用目的。

Predicate通常在List<T> FindAllRemoveAll类的方法。

Action是方法的委托(指针),该方法接受零个,一个或多个输入参数,但不返回任何值。

Func是方法的委托(指针),该方法接受零个,一个或多个输入参数,并返回一个值(或引用)。

谓词是一种常用于比较的 Func。

尽管与 Linq 广泛使用,但是 Action 和 Func 在逻辑上独立于 Linq 的概念。 C ++ 已经以类型化函数指针的形式包含了基本概念。

这是不使用 Linq 的 Action 和 Func 的一个小示例:

class Program
{
    static void Main(string[] args)
    {
        Action<int> myAction = new Action<int>(DoSomething);
        myAction(123);           // Prints out "123"
                                 // can be also called as myAction.Invoke(123);

        Func<int, double> myFunc = new Func<int, double>(CalculateSomething);
        Console.WriteLine(myFunc(5));   // Prints out "2.5"
    }

    static void DoSomething(int i)
    {
        Console.WriteLine(i);
    }

    static double CalculateSomething(int i)
    {
        return (double)i/2;
    }
}

Func-当您想要某个函数的委托时,该委托可以带有或不带有参数并返回值。最常见的示例是从 LINQ 中选择:

var result = someCollection.Select( x => new { x.Name, x.Address });

行动- 当您想要一个函数的委托时,该函数可以或可以不使用参数,并且不返回值。我经常将这些用于匿名事件处理程序:

button1.Click += (sender, e) => { /* Do Some Work */ }

谓词- 当您需要 Func 的专用版本时,该版本可以根据一组条件评估值并返回布尔结果(匹配为 true,否则为 false)。同样,这些在 LINQ 中经常用于类似 Where 的事情:

var filteredResults = 
    someCollection.Where(x => x.someCriteriaHolder == someCriteria);

我只是仔细检查了一下,结果发现 LINQ 不使用谓词。不知道他们为什么做出这个决定... 但是从理论上讲,这仍然是谓词适合的情况。