关于c#:Func vs. Action vs. Predicate

Func vs. Action vs. Predicate

本问题已经有最佳答案,请猛点这里访问。

有了真实的例子和它们的用法,有人能帮助我理解:

  • 我们什么时候需要Func代表?
  • 我们什么时候需要行动代表?
  • 何时需要谓词委托?

  • FuncAction之间的区别只是您是否希望代理返回值(使用Func)或不返回值(使用Action)。

    Func可能是LINQ中最常用的——例如在投影中:

    1
     list.Select(x => x.SomeProperty)

    或过滤:

    1
     list.Where(x => x.SomeValue == someOtherValue)

    或键选择:

    1
     list.Join(otherList, x => x.FirstKey, y => y.SecondKey, ...)

    Action更常用于List.ForEach之类的事情:对列表中的每个项目执行给定的操作。我使用这个的频率比Func少,尽管有时我会对Control.BeginInvokeDispatcher.BeginInvoke这样的东西使用无参数版本。

    Predicate只是一个特例Func真的,是在所有Func和大多数Action代表都来之前介绍的。我怀疑,如果我们已经有了各种形式的FuncActionPredicate就不会被引入……虽然它确实赋予了委托人的使用某种意义,但FuncAction用于广泛不同的目的。

    Predicate主要用于List中的方法,如FindAllRemoveAll


    操作是一个方法的委托(指针),它接受零个、一个或多个输入参数,但不返回任何内容。

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

    谓词是一种特殊的func,常用于比较。

    尽管与LINQ一起广泛使用,但action和func在逻辑上独立于LINQ。C++已经包含了类型化函数指针形式的基本概念。

    下面是一个不使用linq的action和func的小示例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    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中选择:

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

    操作-当您需要一个函数的委托,该函数可以接受参数,也可以不返回值。我经常将这些用于匿名事件处理程序:

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

    谓词-当需要一个专门的func版本时,该版本根据一组条件计算一个值并返回一个布尔结果(匹配为true,否则为false)。同样,在linq中,这些经常用于以下情况:

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

    < /打击>

    我只是反复检查了一下,结果发现Linq不使用谓词。不知道他们为什么做这个决定……但理论上,它仍然是一个谓词适合的情况。