委托是一种定义方法签名的类型,可以与具有兼容签名的任何方法关联。您可以通过委托调用其中已添加的方法列表。委托用于将方法作为参数传递给其他方法。事件处理程序就是通过委托调用的方法。您可以创建一个自定义方法,当发生特定事件时某个类(例如 Windows 控件)就可以调用您的方法。button的单击事件发生后,通过委托这个管道找到用户添加的处理方法,从而执行方法;不必像之前win32程序那样循环等待某个事件消息。

先直接添端代码进来,

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 namespace Test_Delegate
 7 {
 8     //定义一个委托,对应方法签名为 int Fun(int , int )
 9     //编译器会自动生成一个委托类 dgOP,在此相当于声明一个类对象,稍后使用时new实例化
10     //继承链如:Delegate:MulticastDelegate:Delegate:ICloneable,ISerializable
11     public delegate int dgOP(int x, int y);
12     //生成的类形如
13     //sealed class dgOP : System.MulticastDelegate
14     //{
15     //    //构造函数,原理不清楚  !!
16     //    public dgOP(object target,unit functionAddr);
17     //    //成员函数,可在外调用
18     //    public virtual int Invoke(int x, int y);  
19     //    public virtual IAsyncResult BeginInvoke(int x, int y
20     //        , AsyncCallback callback, object @object);
21     //    public virtual int EndInvoke(IAsyncResult result);
22     //}
23     
24     public class SimpleMath
25     {
26         /***********静态方法*******************/
27         public static int Add(int x, int y)
28         {
29             Console.WriteLine("add");
30             return x + y;
31         }
32         public static int Square(int x)
33         {
34             return x * x;
35         }
36         /***********动态方法*******************/
37        
38         public int Sub(int x, int y)
39         {
40             Console.WriteLine("sub");
41             return x - y;
42         }
43     }
44 
45     class Program
46     {
47         static dgOP dg;
48         static void Main(string[] args)
49         {
50             //静态方法
51             //实例化上文中定义的(编译器自动生成的)委托类,并指定方法
52             //+=内部隐式调用dgOP.Combine
53             //Del(new dgOP(SimpleMath.Add));
54             dg = dgOP.Combine(new dgOP(SimpleMath.Add),new dgOP(new SimpleMath().Sub)) as dgOP;
55             //执行调用列表的函数,但最终只返回最后一个函数调用返回值。
56             //dg(10 , 20)内部隐式调用 dg.Invoke(20 , 10)
57             Tools.OutputParams(dg(10 , 20));
58             Tools.OutputParams(dg.Invoke(20, 10));
59             //DisplayDelegate(dg);
60             Tools.NewLine();
61 
62             ////动态方法
63             //SimpleMath m=new SimpleMath();
64             //dgOP dg2 = new dgOP(m.Sub);
65             //Tools.OutputParams(dg2(10,20),dg2.Invoke(20,10));
66             //DisplayDelegate(dg2);
67             ////委托已经声明为方法签名为:void Fun(int x,int y),对应2个参数
68             ////SimpleMath.Square只含一个参数
69             ////dgOP dg3 = new dgOP(SimpleMath.Square);
70 
71             Tools.Pause();
72         }
73 
74         private static void Del(dgOP dgOP)
75         {
76             dg += dgOP;
77         }
78 
79     
80 
81         private static dgOP Del()
82         {
83             dgOP dg = new dgOP(SimpleMath.Add);
84             dg += new dgOP(new SimpleMath().Sub);
85             return dg;
86         }
87 
88         private static void DisplayDelegate(dgOP dg)
89         {
90             //输出委托列表内部的方法签名,类对象
91             foreach (Delegate item in dg.GetInvocationList())
92             {
93                 Tools.OutputParams(item.Method, item.Target);
94             }
95         }
96 
97 
98     }
99 }

Tools类只是个工具,用来输出值至控制台,或者另起一行,停止控制台。

 

委托是最底层,事件是较上层,用来简化处理委托声明,封装维护调用列表。

  1 #region Using directives
  2 
  3 using System;
  4 using System.Collections.Generic;
  5 using System.Text;
  6 
  7 #endregion
  8 
  9 namespace CarEvents
 10 {
 11     class Program
 12     {
 13         static void Main(string[] args)
 14         {
 15             Console.WriteLine("***** Fun with Events *****\n");
 16 
 17             // Make a car as usual. 
 18             Car c1 = new Car("SlugBug", 100, 10);
 19 
 20             // Register event handlers.
 21             c1.AboutToBlow += new Car.CarEventHandler(c1_AboutToBlow);
 22             c1.AboutToBlow += new Car.CarEventHandler(CarIsAlmostDoomed);
 23             c1.AboutToBlow += new Car.CarEventHandler(CarAboutToBlow);
 24 
 25             Car.CarEventHandler d = new Car.CarEventHandler(CarExploded);
 26             c1.Exploded += d;
 27 
 28             // Speed up (this will generate the events.)
 29             Console.WriteLine("***** Speeding up *****");
 30             for (int i = 0; i < 6; i++)
 31                 c1.Accelerate(20);
 32 
 33             // Remove CarExploded method 
 34             // from invocation list.
 35             c1.Exploded -= d;
 36 
 37             Console.WriteLine("\n***** Speeding up *****");
 38             for (int i = 0; i < 6; i++)
 39                 c1.Accelerate(20);
 40 
 41             Console.ReadLine();
 42         }
 43 
 44         static void c1_AboutToBlow(string msg)
 45         {
 46             Console.WriteLine("xxxx");
 47         }
 48 
 49         public static void CarAboutToBlow(string msg)
 50         { Console.WriteLine(msg); }
 51 
 52         public static void CarIsAlmostDoomed(string msg)
 53         { Console.WriteLine("Critical Message from Car: {0}", msg); }
 54 
 55         public static void CarExploded(string msg)
 56         { Console.WriteLine(msg); }
 57 
 58     }
 59 }
 60 
 61 #region Using directives
 62 
 63 using System;
 64 using System.Collections.Generic;
 65 using System.Text;
 66 
 67 #endregion
 68 
 69 namespace CarEvents
 70 {
 71     public class Car
 72     {
 73         //// This delegate works in conjunction with the
 74         //// Car’s events.
 75         //public delegate void CarEventHandler(string msg);
 76 
 77         //// This car can send these events.
 78         //public event CarEventHandler Exploded;
 79         //public event CarEventHandler AboutToBlow;
 80 
 81         public delegate void CarEventHandler(string msg);
 82 
 83         public event CarEventHandler Exploded;
 84         public event CarEventHandler AboutToBlow;
 85         #region Basic Car members...
 86 
 87         #region Nested radio
 88         // Radio as nested type
 89         public class Radio
 90         {
 91             public void TurnOn(bool on)
 92             {
 93                 if (on)
 94                     Console.WriteLine("Jamming...");
 95                 else
 96                     Console.WriteLine("Quiet time...");
 97             }
 98         }
 99         #endregion
100 
101         // Internal state data.
102         private int currSpeed;
103         private int maxSpeed;
104         private string petName;
105 
106         // Is the car alive or dead?
107         bool carIsDead;
108 
109         // A car has-a radio.
110         private Radio theMusicBox = new Radio();
111 
112         public Car()
113         {
114             maxSpeed = 100;
115         }
116 
117         public Car(string name, int max, int curr)
118         {
119             currSpeed = curr;
120             maxSpeed = max;
121             petName = name;
122         }
123 
124         public void CrankTunes(bool state)
125         {
126             theMusicBox.TurnOn(state);
127         }
128         #endregion
129 
130         #region Accelerate method
131         public void Accelerate(int delta)
132         {
133             // If the car is dead, fire Exploded event.
134             if (carIsDead)
135             {
136                 if (Exploded != null)
137                     Exploded("Sorry, this car is dead...");
138             }
139             else
140             {
141                 currSpeed += delta;
142 
143                 // Almost dead?
144                 if (10 == maxSpeed - currSpeed
145                   && AboutToBlow != null)
146                 {
147                     AboutToBlow("Careful buddy!  Gonna blow!");
148                 }
149 
150                 // Still OK!
151                 if (currSpeed >= maxSpeed)
152                     carIsDead = true;
153                 else
154                     Console.WriteLine("->CurrSpeed = {0}", currSpeed);
155             }
156         }
157         #endregion
158 
159     }
160 }
View Code

相关文章: