您的位置:首页 > 其它

委托与事件

2012-07-25 23:20 113 查看
1. 委托的定义

个人理解为将某类方法(方法签名相同,不论是私有方法,公有方法还是静态方法,实例方法)进地类型化的途径。

可以类比于其他的类型例如:System.Int是对整数这一类具有共同特征的数据的一个类型化。

2. 委托的作用

通过委托,可以将某个方法作为参数进行传递。并且能够通过委托对传递的方法以进行签名检查。

3. C#中定义委托

C#中采用如下方式定义委托:

public delegate ReturnType MethodName(Parameters(Type&Name))

例如. public delegate void EventHandler(object sender,EventArgs arg)

4. C#中使用委托

使用委托时需要实例化一个委托。

e.g. EventHandler handler = new EventHandler(this.Method);(在委托实例化的过程中会对Method方法的签名进行验证)

这样即创建了一个委托实例,这个委托实例对方法Method进行了引用封装。接下来我们可以将handler传递或保存至任何需要执行Method方法的地方。

当想执行Method方法时,直接执行委托即可

e.g. handler(null,null);

.Net Runtime被对该委托的调用翻译成对它所封装的方法的调用。

一般委托可以支持同时封装多个签名相同的方法,可以通过handler+= new EventHandler(this.Method2)来实现。当调用handler这个委托实现的时候它所封装的所有方法都会被调用。

3. delegate关键字与Delegate Class的关系

当我们用delegate来定义一个委托时,编译器会为这个关键字所定义的委托创建一个从MulticastDelegate派生的类(从MSDN上看到是这样的).当实例化这个委托时,目标方法的信息(类型/对象 方法信息)会被保存到所派生出来的类的Method和Target属性中。当委托被调用时,实际上是对通过这两个属性所标识的方法的调用。我认为这里面编绎器做了很多的工作。(还有个疑问:定义委托时所定义的委托签名是可存在哪里的呢?)

可以看一下当我们声明一个delegate,编绎器会产生什么样的输出:

声明语句如下:

public delegate void CustomEventHandler(object sender, EventArgs arg);

编绎器输出如下:



可以看到编绎器为生成的Delegate类添加了三个方法用来对委托进行调用。

4. 事件的定义

我理解的事件其实是以委托为基础,.NET Framework提供的一个方便开发者使用的“应用”。编绎器做了一些工作,让使用者不需要知道下层委托的细节。

5. 事件的作用

可以将事件定义为类的成员,类的使用者可以注册该事件(提供一个响应函数)。则在类实现中该事件发生成,使用者会得到通知(提供的响应函数会被调用)。

如以下代码:

public class EventSender
{
public event CustomEventHandler CustomEvent;

public void TriggerEvent()
{
if (CustomEvent != null)
{
CustomEvent(this, null);
}
}
}

public class EventReciever
{
private EventSender sender = new EventSender();

public void Run()
{
sender.CustomEvent += new CustomEventHandler(OnSender_CustomEvent);
sender.TriggerEvent();
}

private void OnSender_CustomEvent(object sender, EventArgs arg)
{
Console.WriteLine("Received");
}
}EventReceiver注册了EventSender的CustomEvent事件,则当TriggerEvent方法被调用的时候。CustomEvent会被触发,EventReceiver的

OnSender_CustomEvent方法会被调用。

6. 委托与事件的区别

事件是基于委托的,从上面的代码来看定义事件其实就是用event关键字去封装一个委托实例。那么我理解为关键的区别在于编绎器对这个event关键字作了哪些额外的工作,那么这便是委托与事件的区别。首先看一下编绎器对如下代码的输出:

源代码:

public class EventSender
{
public event CustomEventHandler CustomEvent;
public CustomEventHandler handler;
public void TriggerEvent()
{
if (CustomEvent != null)
{
CustomEvent(this, null);
}
}
}编绎器输出:



可以看到,对于event这个关键字,编绎器作了如下工作:

将public的event成员翻译成一个private的委托实例加上add_CustomEvent方法和remove_CustomEvent方法。

这样子的话,类的使用者只能使用事件的add和remove方法(实际情况是使用+=和-=,编绎器也会将这两个操作符的翻译成对add和remove的调用)

而对于委托,类的例用者可以完全将其当作类的一个普通的public成员来使用:赋值,调用,+=,-=等操作。

我认为这就是委托与事件的区别。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: