学习《深入理解C#》—— 委托的构成、合并与删除和总结 (第二章1.1---1.4)
目录
简单委托的构成
委托四部曲:
- 声明委托类型。
- 必须有一个方法包含了要执行的方法。
- 必须创建一个委托实例。
- 必须调用委托(invoke)实例
① 声明委托
public delegate void SayHelloWorld(string message); //① 声明委托类型
如上,声明了一个SayHelloWorld的委托类型, 由System.MulticastDelegate派生,而System.MulticastDelegate又派生自 System.Delegate 。与该类型匹配的方法的签名必需使用一个string类型作为参数和返回一个void类型(即没有返回值)。
②要执行的方法
public static void Say(string message) //② 必须有一个方法包含了要执行的代码; { Console.WriteLine(message); }
方法可以是静态方法或者一个实例方法。
③ 必须创建一个委托实例
SayHelloWorld saymessage = new SayHelloWorld(Say); //③ 必须创建一个委托实例
④ 调用(invoke)委托实例
saymessage.Invoke("HelloWorld"); //④ 必须调用(invoke)委托实例
也可以saymessage("HelloWorld");
完整代码:
1 public static class Program 2 { 3 public delegate void SayHelloWorld(string message); //① 声明委托类型 4 static void Main(string[] args) 5 { 6 SayHelloWorld saymessage = new SayHelloWorld(Say); //③ 必须创建一个委托实例 7 saymessage += SayName; //增加委托实例 8 saymessage.Invoke("HelloWorld"); //④ 必须调用(invoke)委托实例 9 saymessage -= Say; //删除委托实例 10 Console.WriteLine("这是一种调用方法:"); 11 12 //返回委托的调用列表 13 System.Delegate[] delegates = saymessage.GetInvocationList(); 14 //注意这里的delegates列表中存储的是SayHelloWorld类型的委托 15 Console.WriteLine("这是二种调用方法:"); 17 foreach (SayHelloWorld say in delegates) 18 { 19 saymessage("HelloWorld"); 20 } 22 Console.ReadKey(); 23 } 24 public static void Say(string message) //② 必须有一个方法包含了要执行的代码; 25 { 26 Console.WriteLine(message); 27 } 28 public static void SayName(string name) 29 { 30 Console.WriteLine(name); 31 } 32 33 }
合并和删除委托
委托实例不只有一个操作,但真实情况要稍微复杂一点,委托实例实际有一个操作列表与之关联。称之为委托实例列表。而我们一般用+=和-=操作符来对委托实例的增加和删除。调用委托实例时,它的所有操作都按顺序执行。如果委托的签名具有一个非 void 的返回类型,则 Invoke 的返回值是最后一个操作的返回值。很少有非 void 的委托实例在它的调用列表中指定多个操作,因为这意味着其他所有操作的返回值永远都看不见。除非每次调用代码使用Delegate.GetInvocationList 获取操作列表时,都显式调用某个委托。如果调用列表中的任何操作抛出一个异常,都会阻止执行后续的操作。
委托总结
- 委托封装了包含特殊返回值和一组参数行为,类似于单一方法接口。
- 委托类型声明中描述的类型签名决定了方法哪个方法可用于委托实例,同时也决定了调用签名。
- 创建委托实例,需要一个方法以及(对于实例方法来说)调用方法的目标。
- 委托实例是不易变的。
- 每个委托实例都包含一个调用列表——一个操作列表。
- 委托实例可以合并到一起,也可以从一个委托实例中删除另一个。
这篇就写到这里。下篇我们将继续学习《深入理解C#》的相关知识。谢谢!