首页 C#委托事件

C#委托事件

举报
开通vip

C#委托事件C#委托事件 Delegate 是在.NET1.0 的时候就已经存在了的特性,因为在准备总结Lambda 表达式的 时候发现自己对Delegate 还没有深刻的理解,所以打算先对Delegate 进行整理一下。 Delegate 中文译为“委托”,MSDN 中对Delegate 是这样进行解释的“C# 中的委托 类似于C 或C++ 中的函数指针。使用委托使程序员可以将方法引用封装在委托对 象内 。然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调 用哪个方法。与C 或C++ 中的函数指针...

C#委托事件
C#委托事件 Delegate 是在.NET1.0 的时候就已经存在了的特性,因为在准备 总结 初级经济法重点总结下载党员个人总结TXt高中句型全总结.doc高中句型全总结.doc理论力学知识点总结pdf Lambda 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 达式的 时候发现自己对Delegate 还没有深刻的理解,所以打算先对Delegate 进行整理一下。 Delegate 中文译为“委托”,MSDN 中对Delegate 是这样进行解释的“C# 中的委托 类似于C 或C++ 中的函数指针。使用委托使程序员可以将方法引用封装在委托对 象内 。然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调 用哪个方法。与C 或C++ 中的函数指针不同,委托是面向对象、类型安全的,并且是安全的 。” 我们来通过一个Demo 来进行理解: class Program { static void OtherClassMethod() { Console .WriteLine(";Delegate an other class's method"; ); } static void Main(string [] args) { var test = new TestDelegate (); test.delegateMethod = new TestDelegate .DelegateMethod (test.NonStaticMethod); test.delegateMethod += new TestDelegate .DelegateMethod (TestDelegate .StaticMethod); test.delegateMethod += Program .OtherClassMethod; test.RunDelegateMethods(); Console .ReadKey(); } } class TestDelegate { // 声明了一个Delegate 类 型名为DelegateMethod ,这种Delegate 类型可以搭载返回值为void ,无参函数 public delegate void DelegateMethod (); // 声明了一个 Delegate 对象,注意一个是类型,一个是对象 public DelegateMethod delegateMethod; public static void StaticMethod() { Console .WriteLine(";Delegate a static method"; ); } public void NonStaticMethod() { Console .WriteLine(";Delegate a non-static method"; ); } public void RunDelegateMethods() { if (delegateMethod != null ) { Console .WriteLine(";---------------------"; ); delegateMethod.Invoke(); Console .WriteLine(";---------------------"; ); } } } 通过: test.delegateMethod = new TestDelegate .DelegateMethod (test.NonStaticMethod); test.delegateMethod += new TestDelegate .DelegateMethod (TestDelegate .StaticMethod); test.delegateMethod += Program .OtherClassMethod; 我们可以发现 delegateMethod 搭载了3 个函数(通过+= 增加搭载的函数,也可以通过 -= 来去掉Delegate 中的某个函数),而且通过delegateMethod.Invoke() 运行被搭载的函 数,这就是Delegate 可以看作为函数指针的原因。而在Java 中没有委托机制,如果向要实 现此功能个人感觉只有通过Java 的内部类来实现。 既然C# 中的委托与C++ 中函数指针如此相似,那么我简单整理一下 Delegate 与函数指针的区别: 1、 一个delegate 对象一次可以搭载多个方法,而不是一次一个。当我们唤起一个搭载 多个方法的delegate ,所有方法以开始被搭载到delegate 对象的顺序依次被唤起; 2、 一个delegate 对象所搭载的方法并不需要属于同一个类别,一个delegate 对象所 搭载的所有方法必须具有与声明时相同的原型和形式,然而这些方法可以有static 也可以 有non-static ,可以由一个或多个不同类别的成员组成; 3、 一个delegate type 的声明在本质上是创建了一个新的subtype instance ,该 subtype 派生自 .NET library framework 的 abstract base classes Delegate 或 MulticastDelegate ,它们提供一组public methods 用以询访delegate 对象或其搭载的方 法(methods ) ,与函数指针不同,委托是面向对象、类型安全并且安全的。 Delegate 的使用场景: 首先先看下面这段代码 class Program { static void Main(string [] args) { var car = new Car (15); new Alerter (car); car.Run(120); Console .ReadKey(); } class Car { public delegate void Notify (int value); public event Notify notifier; private int petrol = 0; public int Petrol { get { return petrol; } set { petrol = value ; if (petrol <; 10) // 当petrol 的值小于10 时出发警报 { if (notifier != null ) { notifier.Invoke(Petrol); } } } } public Car(int petrol) { Petrol = petrol; } public void Run(int speed) { int distance = 0; while (Petrol >; 0) { Thread .Sleep(500); Petrol--; distance += speed; Console .WriteLine(";Car is running... Distance is "; + distance.ToString()); } } } class Alerter { public Alerter(Car car) { car.notifier += new Car .Notify (NotEnoughPetrol); } public void NotEnoughPetrol(int value) { Console .ForegroundColor = ConsoleColor .Red; Console .WriteLine(";You only have "; + value.ToString() + "; gallon petrol left!"; ); Console .ResetColor(); } } } 通过上面的代码,你可能会有这样的疑问,为什么不再public in Petrol 中直接调用 Alerter.NotEnoughtPetrol 呢,因为Car 模块和Alerter 模块本身是两个独立的子系统, 如果直接调用,则程序的耦合性就会增加,这是程序员的大忌。 其实上面的代码是设计模式中的观察者设计模式 的实现,当汽车在运行 中汽油量<;10 时,就会发出警报,在上面的代码中Delegate 相当于一个存放回调函数的函 数指针,使用Delegate ,我们可以非常方便地实现观察者模式。而其实,在需要使用回调 函数时,我们都可以考虑使用Delegate 。 下面我再举个例子吧,取生活中一个场景来说,孩子饿了,要哭,爸爸妈妈听到哭声都会赶 过来。如果按照常规的编程方法,我们可能要在Child 类里边实现一个方法来通知爸爸和妈 妈,假设有一天这家聚会,爷爷奶奶,姥姥姥爷,姑姑婶婶全过来了,那么孩子必须要通知 增加的这些人,我们就不得不修改Child 类里的这个方法。而事实上我们可以这样考虑,将 对孩子哭这一事件关心的一类人抽象出来,爷爷奶奶,姥姥姥爷,姑姑婶婶都从该类派生, 他们有一个公共的代理,只要他们将自己的行为“注册”到这个代理,孩子一哭,所有被注 册进去的事件就会形成一个事件的链表然后顺次执行。在这种模式下Child 类和Observer 类的派生类之间的耦合性大大降低了,我们不需要对Child 类的方法进行任何的修改而只需 要讲Observer 类的派生类的各个实例对象对“孩子哭”这一事件的响应注册到“孩子哭” 中就可以了。 class Program { public delegate void EventHandle (object sender, EventArgs e); class Entry { public static void Main() { Woman woman = new Woman (); Man man = new Man (); Child child = new Child (); child.call += new EventHandle (woman.observer_call); child.call += new EventHandle (man.observer_call); child.observer_call(null , null ); Console .ReadKey(); } } abstract class observer { public event EventHandle call; public void Subto(observer ob) { this .call += new EventHandle (ob.observer_call); } abstract public void observer_call(object sender, EventArgs e); public void Shout() { if (call != null ) { call(this , null ); } } } class Woman : observer { public override void observer_call(object sender, EventArgs e) { Console .WriteLine(";Woman : Oh Baby, mom is coming!"; ); Shout(); } } class Man : observer { public override void observer_call(object sender, EventArgs e) { Console .WriteLine(";Man : Oh Baby, papa is coming!"; ); Shout(); } } class Child : observer { public override void observer_call(object sender, EventArgs e) { Console .WriteLine(";Child : Where are my parents? I'm hungry!"; ); Shout(); } } } 上面我定义了一个委托,它的作用是将被委托的函数以参数形式“传递”给事件,从而构成 一个事件的链表。 说明,委托在编译的时候会编译成类,因为委托是一个类,所以在任何可以声明类的地方都可以声明委托。它定义了方法的类型,使得可以将方法当作另一个方法的参数传递,这种将方法动态的赋给参数的做法,可以避免在程序中大量地使用if else(switch) 语句,同时使得程序具有更好的扩展性; 在上面的“ public event Notify notifier; ”可以改写为“ public Notify notifier; ”这就是我下面需要整理的Delegate 与Event ; Delegate 与Event : 通过项目发现很多时候Delegate 与Event 这两个关键字经常会在一起使用,那两者之间是什么关系呢,通过msdn 的解释是“声明事件:若要在类内声明事件,首先必须声明该事件的委托类型”
本文档为【C#委托事件】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_337177
暂无简介~
格式:doc
大小:23KB
软件:Word
页数:0
分类:生活休闲
上传时间:2017-09-21
浏览量:10