【问题标题】:Delegates: Predicate vs. Action vs. Func代表:谓词 vs. 动作 vs. Func
【发布时间】:2009-02-19 19:49:02
【问题描述】:

有人可以对这 3 个最重要的代表提供一个很好的解释(希望有例子):

  • 谓词
  • 动作
  • 功能

【问题讨论】:

    标签: c# delegates predicate func


    【解决方案1】:
    • Predicate:本质上是Func<T, bool>;提出问题“指定的参数是否满足委托所代表的条件?”用于 List.FindAll 之类的东西。

    • Action:执行给定参数的操作。非常通用的用途。在 LINQ 中使用不多,因为它基本上意味着副作用。

    • Func:在 LINQ 中广泛使用,通常用于转换参数,例如通过将复杂结构投影到一个属性。

    其他重要代表:

    • EventHandler/EventHandler<T>:在整个 WinForms 中使用

    • Comparison<T>:类似于IComparer<T>,但采用代表形式。

    【讨论】:

    • 还有System.Converter<TInput, TOutput>,虽然很少使用。
    • 当需要大量将模型转换为业务类时,转换器是一个很好的代表,即stum.de/2009/12/23/…
    • EventHandler/EventHandler<T> 也出现在 WinForms 之外。
    • @Andy:有点……但在 WPF 中就不那么简单了。我同意它没有任何特定于 WinForms 的内容。
    【解决方案2】:

    ActionFuncPredicate 都属于委托家族。

    Action : 动作可以接受 n 个输入参数,但它返回 void。

    Func : Func 可以接受 n 个输入参数,但它总是返回所提供类型的结果。 Func<T1,T2,T3,TResult>,这里T1,T2,T3是输入参数,TResult是它的输出。

    Predicate : Predicate 也是 Func 的一种形式,但它总是返回 bool。简单来说,它是Func<T,bool> 的包装器。

    【讨论】:

      【解决方案3】:

      除了乔恩的回答,还有

      • Converter<TInput, TOutput>:本质上是Func<TInput, TOutput>,但有语义。由 List.ConvertAll 和 Array.ConvertAll 使用,但个人在其他任何地方都没有见过。

      【讨论】:

        【解决方案4】:

        关于参数的简单示例以及每种类型的返回值

        这个 Func 接受两个 int 参数并返回一个 int。Func 总是有返回类型

         Func<int, int, int> sum = (a, b) => a + b;
         Console.WriteLine(sum(3, 5));//Print 8
        

        在这种情况下 func 没有参数但返回一个字符串

        Func<string> print = () => "Hello world";
        Console.WriteLine(print());//Print Hello world
        

        这个 Action 接受两个 int 参数并返回 void

        Action<int, int> displayInput = (x, y) => Console.WriteLine("First number is :" + x + " , Second number is "+ y);
        displayInput(4, 6); //Print First number is :4 , Second number is :6
        

        这个谓词接受一个参数并且总是返回布尔值。一般来说谓词总是返回布尔值。

        Predicate<int> isPositive = (x) => x > 0;
        Console.WriteLine(isPositive(5));//Print True
        

        【讨论】:

          【解决方案5】:

          MethodInvoker 是 WinForms 开发人员可以使用的一种;它不接受任何参数并且不返回任何结果。它早于 Action,并且在调用 UI 线程时仍然经常使用,因为 BeginInvoke() 等人接受无类型的委托;虽然 Action 也可以。

          myForm.BeginInvoke((MethodInvoker)delegate
          {
            MessageBox.Show("Hello, world...");
          });
          

          我也知道 ThreadStart 和 ParameterizedThreadStart;现在大多数人都会再次替换 Action。

          【讨论】:

            【解决方案6】:

            Predicate、Func 和 Action 是 .NET 的内置委托实例。这些委托实例中的每一个都可以引用或指向具有特定签名的用户方法。

            Action 委托 - Action 委托实例可以指向接受参数并返回 void 的方法。

            Func 委托 - Func 委托实例可以指向采用可变数量参数并返回某种类型的方法。

            谓词 - 谓词类似于 func 委托实例,它们可以指向接受可变数量参数并返回 bool 类型的方法。

            【讨论】:

              【解决方案7】:

              带有 lambda 的动作和函数:

              person p = new person();
              Action<int, int> mydel = p.add;       /*(int a, int b) => { Console.WriteLine(a + b); };*/
              Func<string, string> mydel1 = p.conc; /*(string s) => { return "hello" + s; };*/
              mydel(2, 3);
              string s1=  mydel1(" Akhil");
              Console.WriteLine(s1);
              Console.ReadLine();
              

              【讨论】:

                【解决方案8】:

                Func 对 LINQ 更友好,可以作为参数传入。 (无点)

                谓词不能,必须重新包装。

                Predicate<int> IsPositivePred = i => i > 0;
                Func<int,bool> IsPositiveFunc = i => i > 0;
                
                new []{2,-4}.Where(i=>IsPositivePred(i)); //Wrap again
                
                new []{2,-4}.Where(IsPositivePred);  //Compile Error
                new []{2,-4}.Where(IsPositiveFunc);  //Func as Parameter
                

                【讨论】:

                  猜你喜欢
                  • 2023-02-06
                  • 2019-09-17
                  • 2011-05-18
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-03-09
                  • 2010-10-25
                  相关资源
                  最近更新 更多