C#委托、事件

委托就是定义了方法的模板,委托对于方法就像接口对于类,接口定义了类的一些方法模板,委托的意思是你这个方法

要想委托我做事情呢,就必须遵守我的规矩(返回值、参数类型一致),否则我不睬你。

定义事件的时候用到了委托的名称,例如public event SayHello SayHelloM,这里的SayHello 是委托的名称,这个定

义是说我这个事件只跟这个委托打交道,其他的委托和我没有任何关系,一旦本人(event)有事情发生的时候我就委托给

SayHello,具体怎么做,那是SayHello的事,和我无关,我只注重SayHello办事的结果,有点像黑社会老大叫小弟去做

什么事情,他才不管你怎么做,只要事情能办成就OK。当然了,可能这个老大有很多事情要做,那么可以都委托给这个

小弟去做,小弟说:让我做事是吧,那你得遵守我的规矩(这谁是老大呢?哈哈)。

 

下面我们看一个简单的例子:

View Code
 1  public delegate void SayHello(string name);
 2 
 3     public class HelloMethod
 4     {
 5         public static void Chinese(string name)
 6         {
 7             Console.WriteLine("你好," + name);
 8         }
 9 
10         public static void Foreigner(string name)
11         {
12             Console.WriteLine("Hello," + name);
13         }        
14     }
15     public class Program
16     {        
17         public event SayHello SayHelloM;
18 
19         public static void Main(string[] args)
20         {
21             Program p = new Program();
22             //用方法名实例化委托
23             SayHello helloChinese = new SayHello(HelloMethod.Chinese);
24             SayHello helloForeigner = new SayHello(HelloMethod.Foreigner);
25             helloChinese("张三");
26             helloForeigner("Jim");
27 
28             //如果事件发生了,就通知委托,具体做什么由委托决定
29             p.SayHelloM += helloChinese;
30             p.SayHelloM += helloForeigner;
31             p.SayHelloM("王六");
32             Console.ReadKey();            
33         }
34     }

 

 

 程序1:

View Code
 1 public delegate void GreetingDelegate(string name);   //具体的说,这里定义的是MakeGreeting的返回值和参数类型
 2     class Program
 3     {
 4         private static void EnglishGreeting(string name)
 5         {
 6             Console.WriteLine("Hello,"+name);
 7         }
 8 
 9         private static void ChineseGreeting(string name)
10         {
11             Console.WriteLine("你好," + name);
12         }
13         //将委托作为参数类型代表方法,委托的参数类型和返回值类型和接受方法的参数类型和返回值的参数类型相同
14         private static void GreetPeople(string name, GreetingDelegate MakeGreeting)   
15         {
16             MakeGreeting(name);
17         }
18 
19         //这个函数用来和GreetPeople(string name, GreetingDelegate MakeGreeting)函数对照理解
20         private static void GreetPeople(string name, string MethodName)
21         {
22             if (MethodName.Equals("ChineseGreeting"))
23             {
24                 ChineseGreeting(name);
25             }
26             else if (MethodName.Equals("EnglishGreeting"))
27             {
28                 EnglishGreeting(name);
29             }
30         }
31 
32         public static void Main(string[] args)
33         {
34             GreetPeople("张三", ChineseGreeting); 
35             GreetPeople("Jim", EnglishGreeting);
36             //或者
37             GreetingDelegate delegat1, delegat2;
38             delegat1 = ChineseGreeting;
39             delegat2 = EnglishGreeting;
40             string name1 = "张三";
41             string name2= "Jim";
42             GreetPeople(name1, delegat1);
43             GreetPeople(name2, delegat2);
44             //当然,可以将多个方法赋给一个委托
45             GreetingDelegate dele;
46             dele = ChineseGreeting;   //赋值
47             dele += EnglishGreeting;  //绑定
48             GreetPeople("张三", dele);
49             //通过委托直接调用ChineseGreeting和EnglishGreeting方法
50             GreetingDelegate deleg;
51             deleg = ChineseGreeting;
52             deleg += EnglishGreeting;
53             deleg("张三");
54             //简化过程
55             GreetingDelegate del = new GreetingDelegate(ChineseGreeting);
56             del += EnglishGreeting;
57 
58             Console.ReadKey();
59         }

分析:略

程序2:

View Code
 1     public delegate void GreetingDelegate(string name);   //这里的返回值类型、参数类型和MakeGreeting的返回值类型、参数类型相同
 2     //定义一个类用于封装委托
 3     public class GreetManager
 4     {
 5         //封装委托变量,不需要在主方法中再声明委托变量,这样体现了面向对象封装的特性
 6         //但是此处是public,这样在客户端就可以随意的对变量进行进行赋值,严重破坏了封装特性
 7         public GreetingDelegate deleg; 
 8         //将委托作为参数类型代表方法,参数类型和返回值类型相同
 9         public void GreetPeople(string name, GreetingDelegate MakeGreeting)   
10         {
11             MakeGreeting(name);
12         }
13         //和public void GreetPeople(string name, GreetingDelegate MakeGreeting)得到的结果一样
14         public void GreetPeople(string name)
15         {
16             if (deleg != null)  //如果有方法注册委托变量
17             {
18                 deleg(name);   //通过委托调用方法
19             }
20         }
21     }
22 
23     class Program
24     {
25         private static void EnglishGreeting(string name)
26         {
27             Console.WriteLine("Hello," + name);
28         }
29 
30         private static void ChineseGreeting(string name)
31         {
32             Console.WriteLine("你好," + name);
33         }
34         public static void Main(string[] args)
35         {
36             GreetManager manager = new GreetManager();
37             GreetingDelegate dele;
38 
39             dele = ChineseGreeting;
40             dele += EnglishGreeting;
41             manager.GreetPeople("张三", dele);
42 
43             manager.deleg = ChineseGreeting;//这里调用的deleg是GreetManager类中的委托变量,类型为public
44             manager.deleg += EnglishGreeting;
45             manager.GreetPeople("赵四", manager.deleg);  //这里不是很美好啊
46 
47             manager.deleg = ChineseGreeting;
48             manager.deleg += EnglishGreeting;
49             manager.GreetPeople("王武");  //这里不需要再传递deleg变量
50 
51             Console.ReadKey();
52         }
53     }

分析:略

程序3:

View Code
 1     public delegate void GreetingDelegate(string name);   
 2 
 3     public class GreetManager
 4     {
 5         //此处使用事件属性实现封装,实质是进行事件的声明
 6         //这里说明了声明事件就是对委托类型的变量进行封装
 7         //该委托变量在编译时会被编译成私有字段
 8         public event GreetingDelegate MakeGreet;
 9 
10         public void GreetPeople(string name)
11         {
12             if (MakeGreet != null)  //如果有方法注册委托变量
13             {
14                 MakeGreet(name);   //通过委托调用方法
15             }
16         }
17     }
18 
19     class Program
20     {
21         private static void EnglishGreeting(string name)
22         {
23             Console.WriteLine("Hello," + name);
24         }
25 
26         private static void ChineseGreeting(string name)
27         {
28             Console.WriteLine("你好," + name);
29         }
30         public static void Main(string[] args)
31         {
32             GreetManager manager = new GreetManager();
33             //manager.MakeGreet = ChineseGreeting;   //这样写编译错误,因为MakeGreet在编译时被编译为私有变量,所以不允许赋值
34             manager.MakeGreet += ChineseGreeting;
35             manager.MakeGreet += EnglishGreeting;
36             manager.GreetPeople("张三");
37 
38             Console.ReadKey();
39         }
40     }

 分析:略

posted @ 2012-09-04 16:33  jsping68  阅读(202)  评论(0编辑  收藏  举报