• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#委托初探

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

委托是一种定义方法签名的类型,可以与具有兼容签名的任何方法关联。您可以通过委托调用其中已添加的方法列表。委托用于将方法作为参数传递给其他方法。事件处理程序就是通过委托调用的方法。您可以创建一个自定义方法,当发生特定事件时某个类(例如 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

匿名方法是简化了委托及方法定义,不必再手动定义方法,直接间写在委托中。

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

                      

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#方法里面的默认参数发布时间:2022-07-13
下一篇:
C#.NET大文件分片上传/多线程上传发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap