Func vs. Action vs. Predicate

时间:2010-11-30 19:07:49

标签: c# delegates

通过实例及其用法,有人可以帮助我理解:

  1. 我们什么时候需要Func委托?
  2. 我们什么时候需要行动委托?
  3. 我们什么时候需要Predicates delegate?

3 个答案:

答案 0 :(得分:845)

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之类的事情:对列表中的每个项目执行给定的操作。虽然我有时会使用无参数版本来处理FuncControl.BeginInvoke等内容,但我的使用频率低于Dispatcher.BeginInvoke

Predicate只是一个特殊的Func<T, bool>,在所有Func和大多数Action代表出现之前就已经介绍过了。我怀疑如果我们已经有FuncAction各种伪装,Predicate就不会被引入......虽然它 传授对代表的使用具有某种意义,而FuncAction用于广泛不同的目的。

Predicate主要用于List<T>,用于FindAllRemoveAll等方法。

答案 1 :(得分:336)

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

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

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

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

以下是Action和Func的一个小例子,不使用Linq:

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;
    }
}

答案 2 :(得分:62)

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不使用Predicates。不知道为什么他们做出了这个决定......但理论上它仍然是谓词适合的情况。