1.委托的定义
委托可以看成是一种数据类型,可以用于定义变量能接受的值只能是一个方法。
委托简单的示例:
1 namespace DelegateDemo 2 { 3 class Program 4 { 5 public delegate int MathOptDelegate(int value1,int value2); 6 public int add(int value1, int value2) 7 { 8 return value1 + value2; 9 } 10 11 static void Main(string[] args) 12 { 13 MathOptDelegate mod; 14 Program p = new Program(); 15 mod =p.add; 16 Console.WriteLine(mod(3,5)); 17 Console.ReadKey(); 18 } 19 } 20 }
利用委托的构造函数创建委托
1 namespace DelegateDemo 2 { 3 class Program 4 { 5 public delegate int MathOptDelegate(int value1,int value2); 6 public int add(int value1, int value2) 7 { 8 return value1 + value2; 9 } 10 11 static void Main(string[] args) 12 { 13 14 Program p = new Program(); 15 MathOptDelegate mod = new MathOptDelegate(p.add); 16 Console.WriteLine(mod(3,5)); 17 Console.ReadKey(); 18 } 19 } 20 }
从这个示例中可以得出这样的直观印象:
委托可以堪称是一个方法的容器,将某一个具体的方法装入后,就可以把它当成方法一样使用。
2.委托的调用列表
从上一个例子看,委托变量可以引用某一个方法,调用它就相当于调用这个方法。
如果委托今年仅是方法调用的另一种形式,那何必多此一举引入委托这一特性?直接调用方法不是更简单明了?
因为委托变量不仅可以引用另一个方法,还可以组合多的方法并批量执行它们。
namespace DelegateDemo2 { class Program { public delegate void MyDelegate(String str); public static void hello(String str) { Console.WriteLine(str+"你好"); } public static void goodbye(String str) { Console.WriteLine(str+"再见"); } static void Main(string[] args) { MyDelegate a,b,c,d; a = Program.hello; a("a"); b = Program.goodbye; b("b"); c = a + b;//等价将两个方法体合并 c("c");// c你好 c再见 d = c - a; d("d");//d再见 Console.ReadKey(); } } }
像C这样的委托变量可称为多路委托变量。
可以用加法运算符来组合单个委托变量为多路委托变量。类似的,也可以使用减法运算符来从一个多路委托变量中移除某个委托变量。
namespace DelegateDemo2 { class Program { public delegate void MyDelegate(String str); public static void hello(String str) { Console.WriteLine(str+"你好"); } public static void goodbye(String str) { Console.WriteLine(str+"再见"); } static void Main(string[] args) { MyDelegate a,b,c,d; a = Program.hello; a("a"); b = Program.goodbye; b("b"); c = a + b;//等价将两个方法体合并 c("c");// c你好 c再见 d = c - a; d("d");//d再见 Delegate[] ds; ds = c.GetInvocationList(); foreach(Delegate s in ds) { Console.WriteLine(s); //DelegateDemo2.Program+MyDelegate //DelegateDemo2.Program+MyDelegate } Console.WriteLine(ds.Length); Console.ReadKey(); } } }
如果委托定义的方法有返回值,则多路委托变量的返回值为委托调用列表中最后一个方法的返回值,中间调用的方法返回值会被丢弃。
使用泛型委托:
Func系列委托
以下是Func熄了委托的定义,依其泛型类型参数的多少有多个重载形式:
public delegate TResult Func<Tresult>();
public delegate TResult Func<T,Tresult>();