zoukankan      html  css  js  c++  java
  • C# Action 和 Func 区别

    前言:

      1.委托是一个类,定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递。

         把一个 参数类型 返回值 相同 方法名不同 的方法当变量 的方法 叫委托。

       为了实现程序的六大设计中的开闭原则:解耦,对修改关闭,对扩展开放。逻辑分离。

          直接调用函数和使用委托调用函数的区别就是是否方便对外扩展。

         当我们窗体传值、线程启动时绑定方法、lambda表达式、异步等等情况下需要用到。

      2.事件是一种特殊的委托,本质就是委托,事件是回调机制的一种应用。

         当委托调用的函数达到某种条件时,可以通过回调通知调用者。

    一:委托的申明

      1. delegate  ,至少0个参数,至多32个参数,可以无返回值,可以指定返回值类型

           eg: public delegate int MethodDelegate(int x,int y);    //两个参数,返回int类型

      2. Action  ,至少0个参数,无返回值的泛型委托

        Action<int,string,bool> ,有传入int、string、bool类型的参数,无返回值的委托

        eg: public void Test<Test>(Action<T> action,T p) {   actoin(p);   }

      3. Func  ,至少0个参数,至多16个参数,必须有返回值的泛型委托

        Func<object,string,int> ,传入参数为object、string类型的参数,返回值为int的委托

        eg: public int Test<T1, T2>(Func<T1, T2, int>func,T1 a,T2 b){    return func(a, b);    }

      4.Predicate  ,有且只有一个参数,返回值只为 bool 类型

        predicate<int> 表示传入为int类型的参数,返回bool类型的委托。

        eg: public delegate bool Predicate<T>(T obj)

    二:委托的使用

      1. delegate 

        public delegate int MethodDelegate(int x,int y);
        private static MethodDelegate method;
        static void Main(string[]  args)
        {
          method = new MethodDelegate(Add);
          method(10,20);  
        }
           private static int Add(int x, int y)
        {
          return x +y;
        }

      2. Action 

        static void Main(string[] args)
        {
          Test<string>(Action, "Hello World");
          Test<string>(p => { Console.WriteLine("{0}", p); }, "Hello World" );
        }
        public static void Action(string s)
        {
          Console.WriteLine(s);
        }
        public static void Test<T>(Action<T> action,T p)
        {
          action(p);  
        }

      3. Func的使用

        static void Main(string[] args)
        {
          Test<int, int>(Fun, 100, 200);
        }
        public static int Test <T1, T2>(Func<T1, T2, int>func, T1 a,T2 b)
        {
          return func(a ,b);
        }
        private static int Fun(int a ,int b)
        {
          return a + b;
        }

      4. predicate 的使用

       static void Main(string[] args)
       {
          Point[] points = {
            new Point(100,200) ,
            new Point(250,375),
            new Point(150,250),
            new Point(275,395),
            new Point(295,450)
          };
          Point first = Array.Find(points,ProductGT10) ;
          Console.WriteLine("Found: X = {0},Y = {1}", frist.x, frist.Y);
       }
       private static bool ProductGT10(Point p)
       {
          if(p.X * p.Y > 100000)
          {
            return true;
          }
          else
          {
            return false;
          }
       }

    三:委托的清空

      1.在类中循环去除委托引用

        public MethodDelegate OnDelegate;
       public void ClearDelegate()
       {
          while(this.OnDelegate != null)
          {
            this.OnDelegate -= this.OnDelegate;
          }
       }

      2.在方法中查询出委托后去除

      public MethodDelegate OnDelegate;
      static void  Main(string[] args)
      {
        Program test = new Program();
        if(test.OnDelegate != null)
        {
           System.Delegate[] dels = test.OnDelegate.GetInvocationList();
           for(int 1 = 0; i < dels.Length; i++)
            {
             test.OnDelegate -= dels[i] as MethodDelegate;
           }
        }
      }

     PS:下面三种方式属于老式委托的使用,就不要用了。C#3.5之后都用  Action Func

     WithParaNoReturnEventHandler _WithParaNoReturnEventHandler = new WithParaNoReturnEventHandler(MyDelegate.SayChinese);
     MyDelegate.Say("张三",_WithParaNoReturnEventHandler);  //C#1.0 传统调用
     MyDelegate.Say("张三", delegate(string name) { Console.WriteLine("你好," + name); }); //C#2.0 匿名方法
     MyDelegate.Say("张三", (name) => { Console.WriteLine("你好," + name); }); //C#3.0 lambda表达式

      

  • 相关阅读:
    1062 Talent and Virtue (25 分)
    1083 List Grades (25 分)
    1149 Dangerous Goods Packaging (25 分)
    1121 Damn Single (25 分)
    1120 Friend Numbers (20 分)
    1084 Broken Keyboard (20 分)
    1092 To Buy or Not to Buy (20 分)
    数组与链表
    二叉树
    时间复杂度与空间复杂度
  • 原文地址:https://www.cnblogs.com/HansZimmer/p/13964475.html
Copyright © 2011-2022 走看看