代码改变世界

委托学习(2)

2014-08-07 20:50  wuzhang  阅读(505)  评论(0编辑  收藏  举报

1.1 委托链

  委托是多路广播的,因此可以将两个或多个非委托实例组合到一起,构成委托链。所谓委托链就是被委托的的方法用链表的形式连接在一起。

  关于委托链的形成在C#中使用二元+和+=运算符来来组合委托,使用-或-=运算符来从委托链中移除一个委托。

  当组合连个委托或者从一个委托链中移除一个委托实例时,将产生一个新的委托。该委托有自己的调用列表,被组合或移除的委托的调用列表将保持不变、  

  如果一个委托实例的列表中包含多个方法,那么调用这样的委托实例时将会按照调用列表的顺序执行方法。如果参数含引用或输出参数(ref或out参数),那么每个方法都

  将使用对同一变量的引用,因此,如果调用列表中的某个方法对该变量进行修改之后的所有委托方法豆浆使用修改过的变量作为参数。如果委托调用包含引用或输出参数或  

  一个返回值,那么该返回值有调用列表中的最后一个方法所决定。

那就看一个委托链的简单实例吧!

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 
  7 namespace Delegate2
  8 {
  9     //声明委托
 10     public delegate void PrintHandler(string message);
 11 
 12     //定义类1的委托方法;
 13     public class PrintProvider1
 14     {
 15         public void Print(string msg)
 16         {
 17             Console.WriteLine("++++++1"+msg.ToString()+"++++++");
 18         }
 19     }
 20     //定义类2的委托方法;
 21     public class PrintProvider2
 22     {
 23         public void Prinit(string msg)
 24         {
 25             Console.WriteLine("------2"+msg.ToString()+"-------");
 26         }
 27     }
 28 
 29     class Test
 30     {
 31         //静态被委托的方法
 32         static void StaticPrint(string msg)
 33         {
 34             Console.WriteLine("######3"+msg.ToString()+"######");
 35         }
 36 
 37         static void Main(string[] args)
 38         {
 39             string s = "委托链";
 40 
 41             //实例两个PrintProvider类的对象
 42             PrintProvider1 pp1 = new PrintProvider1();
 43             PrintProvider2 pp2 = new PrintProvider2();
 44 
 45             //委托对象1的实例
 46             PrintHandler prn1 = new PrintHandler(pp1.Print);
 47             Console.WriteLine("\n委托实例1打印的结果:");
 48             prn1(s);
 49 
 50             //委托对象2的实例
 51             PrintHandler prn2 = new PrintHandler(pp2.Prinit);
 52             Console.WriteLine("\n委托实例2打印的结果:");
 53             prn2(s);
 54 
 55             //委托对象3的实例
 56             PrintHandler prn3 = new PrintHandler(Test.StaticPrint);
 57             Console.WriteLine("\n委托实例3打印的结果:");
 58             prn3(s);
 59 
 60             //委托链的增加
 61             Console.WriteLine("\n委托实例prn+prn2的结果:");
 62             PrintHandler prn = prn1 + prn2;
 63             prn(s);
 64 
 65             Console.WriteLine("\n委托实例prn+prn2+prn3的结果:");
 66             prn += prn3;
 67             prn(s);
 68 
 69             //委托的移除
 70             Console.WriteLine("\n委托实例prn1+prn3");
 71             prn -= prn2;
 72             prn(s);
 73 
 74             Console.WriteLine("\n委托实例prn3");
 75             prn -= prn1;
 76             prn(s);
 77 
 78             Console.WriteLine("\n试图调用空的委托链引发异常");
 79             try
 80             {
 81                 //委托移除
 82                 //prn = (PrintHandler)Delegate.Remove(prn, new PrintHandler(pp1.Print));
 83                 prn -= prn3;
 84                 prn(s);
 85             }
 86             catch (NullReferenceException ex)
 87             {
 88                 Console.WriteLine(ex.Message);
 89             }
 90 
 91             Console.WriteLine("\n试图从null的委托链移除委托,无效");
 92             try
 93             {
 94                 prn -= prn;
 95                 prn(s);
 96             }
 97             catch(NullReferenceException ex)
 98             {
 99                 Console.WriteLine(ex.Message);
100             }
101 
102             Console.ReadLine();
103         }
104 
105     }
106 }
View Code


运行结果:

 

希望大家共同学习,明天继续学习匿名委托。