委托与事件
2012-07-25 23:20
113 查看
1. 委托的定义
我理解的事件其实是以委托为基础,.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成员来使用:赋值,调用,+=,-=等操作。
我认为这就是委托与事件的区别。
个人理解为将某类方法(方法签名相同,不论是私有方法,公有方法还是静态方法,实例方法)进地类型化的途径。
可以类比于其他的类型例如:System.Int是对整数这一类具有共同特征的数据的一个类型化。
2. 委托的作用可以类比于其他的类型例如:System.Int是对整数这一类具有共同特征的数据的一个类型化。
通过委托,可以将某个方法作为参数进行传递。并且能够通过委托对传递的方法以进行签名检查。
3. C#中定义委托C#中采用如下方式定义委托:
public delegate ReturnType MethodName(Parameters(Type&Name))
例如. public delegate void EventHandler(object sender,EventArgs arg)
4. C#中使用委托public delegate ReturnType MethodName(Parameters(Type&Name))
例如. public delegate void EventHandler(object sender,EventArgs arg)
使用委托时需要实例化一个委托。
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的关系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这个委托实现的时候它所封装的所有方法都会被调用。
当我们用delegate来定义一个委托时,编译器会为这个关键字所定义的委托创建一个从MulticastDelegate派生的类(从MSDN上看到是这样的).当实例化这个委托时,目标方法的信息(类型/对象 方法信息)会被保存到所派生出来的类的Method和Target属性中。当委托被调用时,实际上是对通过这两个属性所标识的方法的调用。我认为这里面编绎器做了很多的工作。(还有个疑问:定义委托时所定义的委托签名是可存在哪里的呢?)
可以看一下当我们声明一个delegate,编绎器会产生什么样的输出:
声明语句如下:
public delegate void CustomEventHandler(object sender, EventArgs arg);
编绎器输出如下:
可以看到编绎器为生成的Delegate类添加了三个方法用来对委托进行调用。
4. 事件的定义可以看一下当我们声明一个delegate,编绎器会产生什么样的输出:
声明语句如下:
public delegate void CustomEventHandler(object sender, EventArgs arg);
编绎器输出如下:
可以看到编绎器为生成的Delegate类添加了三个方法用来对委托进行调用。
我理解的事件其实是以委托为基础,.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成员来使用:赋值,调用,+=,-=等操作。
我认为这就是委托与事件的区别。