C# 委托、事件
来源:互联网 发布:审计软件 编辑:程序博客网 时间:2024/06/06 00:26
C#的Delegate委托可以把方法当做参数传递,方便我们回调方法,它的用处很多,为我们编程提供了很大的便利。而Event又是委托的特殊形式。
委托Delegate
public delegate void GreetingDelegate(string name);delegate 是委托的关键字,GreetingDelegate是一个委托类名,在编译后,它会由编译器生成委托类
public sealed class GreetingDelegate:Syste.MulticastDelegate{public GreetingDelegate(object @object, IntPtr method);public virtual IAsyncResult BeginInvoke(string name, AsyncCallback callback, object @object);public virtual void EndInvoke(IAsyncResult result);public virtual void Invoke(string name);}
(BeginInvoke和EndInvoke,是对委托异步回调的支持,关于异步回调,会在后面文章中涉及。)
方法定义,此方法只要传入参数和返回类型与委托定义的一样,就可以赋值给委托
public void EnglishGreeting(string name){}首先委托类可以像参数一样传递在方法,属性中,如下:
public void GreetPeople(string name, GreetingDelegate MakeGreeting){ MakeGreeting(name);}然后可以按下面的方式调用此方法:
GreetPeople("Jimmy Zhang", EnglishGreeting); //这代码看着有点奇怪吧?直接把方法作为了参数传递
委托类是需要实例化的,其实上面的方法内部已经帮你实例化了。它的实例化过程如下:
GreetingDelegate delegate1;delegate1 = EnglishGreeting;// 以赋值的方式实例化GreetingDelegate delegate1 = new GreetingDelegate(EnglishGreeting);//以构造方法方式实例化委托可以通过赋值方式实例化,也可以通过构造方式实例化,GreetPeople("Jimmy Zhang", EnglishGreeting)这里是通过赋值的方式实例化的
可以将多个方法赋给同一个委托,或者叫将多个方法绑定到同一个委托,当调用这个委托的时候,将依次调用其所绑定的方法。
delegate1 = EnglishGreeting; // 先给委托类型的变量赋值delegate1 += ChineseGreeting; // 给此委托变量再绑定一个方法delegate1 -= ChineseGreeting; //当然也可以去掉一个委托方法
Event 事件
public event GreetingDelegate MakeGreet;
定义中多了event关键字,GreetingDelegate是上面定义的委托名。它封装了委托类型的变量,使得在类的内部,不管你声明它是public还是protected,它总是private的。在类的内部,可以直接调用它。在类的外部,只能使用+=或-=为它注册事件的执行方法,不能调用它去执行,这个是类的封装,只能由内部去触发事件(但是delegate是可以在外部直接调用,不需要封装方法的)。
委托事件
按照.Net Framework的编码规范:委托事件的名称都应该以EventHandler结束。 委托事件的原型定义:有一个void返回值,并接受两个输入参数:一个Object 类型,一个 EventArgs类型(或继承自EventArgs)。 事件的命名为 委托去掉 EventHandler之后剩余的部分。 继承自EventArgs的类型应该以EventArgs结尾。
定义委托事件的代码如下:
public delegate void ShowMessageEventHandler(Object sender, MessageEventArgs e); sender参数可以传递是谁触发的,e参数可以自定义一些需要的信息public event ShowMessageEventHandler ShowMessage; // 命名规范,一般以EventHandler结尾。定义eventargs
public class MessageEventArgs : EventArgs{//内部可以定义自己想要的信息}//注册的方法,方法签名必须与定义的委托的方法的签名相同void EventTest_ShowMessage(object sender, MessageEventArgs e){ Console.WriteLine("you have triggered ShowMessage event");}
注册事件
ShowMessage += EventTest_ShowMessage;
注册的时间可以是new ShowMessageEventHandler(EventTest_ShowMessage),也可以是+=,也可以用-=移出注册的事件
触发事件
ShowMessage(this, new MessageEventArgs());//如果在定义此事件的内部类,可以用这种方式直接触发。
在类的外部想调用ShowMessage,需要封装成一个方法,虽然是public的,但因为有event关键字,所以是无法编译通过的。如 public void TriggerEvent() { if (ShowMessage != null) { ShowMessage(this, new MessageEventArgs("event is from trigger")); } }经过测试,对于event事件,定义时也可以是如下的这种形式 public delegate void NoParamEventHandler(); public event NoParamEventHandler NoParam; public void NoParamMethod() { Console.WriteLine("you have triggered NoParam event"); }注册 NoParam += NoParamMethod;触发NoParam();所以对于event与delegate的区别,<pre name="code" class="html">我的理解是虽然可以类似delegate一样使用,但事件是具有特殊含义的,专门用来处理事件模型,但是最好还是按照clr的编码规范来定义和使用,这样方便大家对代码的阅读和理解。顺便讲一下Func和Action,这2个是已经为我们定义好了的委托,方便让我们使用,我们不需要自己定义委托,直接可以用Func<T,TResult>和Action<T>,把签名一样的方法赋值给它们。
- C#委托及事件委托
- c# 委托和委托事件
- C# 事件 委托 教程
- C# 事件 委托 教程
- C#委托及事件
- c# 委托与事件
- C# 委托和事件
- C#委托与事件
- C#委托,事件
- C#委托事件
- C#委托及事件
- c# 委托 和 事件
- C#委托,事件
- C#委托及事件
- 关于 C# 委托、事件
- C# 委托与事件
- C#委托事件
- c#委托、事件理解
- android 调用onPrepareOptionsMenu问题
- WebSocket Java Programming入门-1(annotated)
- Memcache,Redis,MongoDB(数据缓存系统)方案对比与分析
- HTML5 localstorage 安全分析
- gem5源代码文件结构作用介绍
- C# 委托、事件
- CUDA复数类的定义
- 数据结构之图
- 淘宝,京东,苏宁易购技术架构(路线)分析和比较
- Unable to instantiate application io.rong.app.App: java.lang.ClassNotFoundException:
- 优先队列 阿格斯(Argus Beijing La 3135)
- read命令
- 如何正确关机/重启
- Head First HTML5 Programming—每天一小步-(一)