你的位置:首页 > ASP.net教程

[ASP.net教程]委托, 泛型委托,FuncT和ActionT


使用委托来做一些事情,大致思路是:

1、定义声明一个委托,规定输入参数和输出类型。
2、写几个符合委托定义的方法。
3、把方法列表赋值给委托
4、执行委托

 

  internal delegate int MyDelegate();
  class Program
  {
    static void Main(string[] args)
    {
      MyDelegate d = ReturnOne;
      d += ReturnTwo;
      foreach (int i in GetAllReturnVals(d))
      {
        Console.WriteLine(i);
      }
      Console.ReadKey();
    }
    static IEnumerable<int> GetAllReturnVals(MyDelegate myDelegate)
    {
      foreach (MyDelegate del in myDelegate.GetInvocationList())
      {
        yield return del();
      }
    }
    static int ReturnOne()
    {
      return 1;
    }
    static int ReturnTwo()
    {
      return 2;
    }
  }

 

以上,委托的返回类型是int,如果让返回类型是泛型呢?只要让以上的GetAllReturnVals方法针对泛型就可以了。

 

  internal delegate T MyDelegate<T>();
  class Program
  {
    static void Main(string[] args)
    {
      MyDelegate<int> d = ReturnOne;
      d += ReturnTwo;
      foreach (int i in GetAllReturnVals(d))
      {
        Console.WriteLine(i);
      }
      MyDelegate<string> d1 = ReturnA;
      d1 += ReturnB;
      foreach (string s in GetAllReturnVals(d1))
      {
        Console.WriteLine(s);
      }
      Console.ReadKey();
    }
    //返回所有委托方法的执行结果
    static IEnumerable<T> GetAllReturnVals<T>(MyDelegate<T> myDelegate)
    {
      foreach (MyDelegate<T> del in myDelegate.GetInvocationList())
      {
        yield return del();
      }
    }
    static int ReturnOne()
    {
      return 1;
    }
    static int ReturnTwo()
    {
      return 2;
    }
    static string ReturnA()
    {
      return "A";
    }
    static string ReturnB()
    {
      return "B";
    }
  }

 

不过,.NET还为我们准备了一个更"懒 "的方法,那就是针对泛型的委托Func<T>,这下,连委托都不要事先声明了。Func<T>的<>中的泛型列表的最后一个是返回类型,其它的都是输入类型,Func<T>多达十几个重载。

 

  class Program
  {
    static void Main(string[] args)
    {
      Func<int> d = ReturnOne;
      d += ReturnTwo;
      foreach (int i in GetAllReturnVals(d))
      {
        Console.WriteLine(i);
      }
      Func<string> d1 = ReturnA;
      d1 += ReturnB;
      foreach (string s in GetAllReturnVals(d1))
      {
        Console.WriteLine(s);
      }
      Console.ReadKey();
    }
    //返回所有委托方法的执行结果
    static IEnumerable<T> GetAllReturnVals<T>(Func<T> myDelegate)
    {
      foreach (Func<T> del in myDelegate.GetInvocationList())
      {
        yield return del();
      }
    }
    static int ReturnOne()
    {
      return 1;
    }
    static int ReturnTwo()
    {
      return 2;
    }
    static string ReturnA()
    {
      return "A";
    }
    static string ReturnB()
    {
      return "B";
    }
  }

 

以上泛型委托Func<T>同时有输入参数和返回类型,如果返回类型为void,那就可以使用Action<T>了,当然Action<T>也有多达十几个重载。

 

  class Program
  {
    static void Main(string[] args)
    {
      Action<int> a1 = ReturnInt;
      a1(1);
      Action<string> a2 = ReturnStr;
      a2("hello");
  
      Console.ReadKey();
    }
    static void ReturnStr(string s)
    {
      Console.WriteLine(s);
    }
    static void ReturnInt(int a) 
    {
      Console.WriteLine(a);
    }
  }

 

总结:Func<T>和Action<T>是泛型委托的"语法糖",如果返回类型为void,那就使用Action<T>,否则使用Func<T>。