现在的位置: 首页 > 综合 > 正文

说说Delegate和Event

2012年09月20日 ⁄ 综合 ⁄ 共 2185字 ⁄ 字号 评论关闭

Delegate和Event,在C#中,常常看到他们在一起使用,这其中有什么奥秘呢,在这里我说说我看到的,我们以下边的代码为例:

 1using System;
 2
 3//Delegate
 4delegate void UpdateDelegate();
 5
 6//Subject
 7class Subject
 8{
 9    public event UpdateDelegate UpdateHandler;
10
11    // Methods
12    public void Attach(UpdateDelegate ud)
13    {
14        UpdateHandler += ud;
15    }

16
17    public void Detach(UpdateDelegate ud)
18    {
19        UpdateHandler -= ud;
20    }

21
22    public void Notify()
23    {
24        if (UpdateHandler != null) UpdateHandler();
25    }

26
27}

28public class Client
29{
30    static void UpdateDelegateMethod()
31    {
32        Console.WriteLine("hello world");
33    }

34
35    public static void Main(string[] args)
36    {
37        Subject sj = new Subject();
38        sj.UpdateHandler += new UpdateDelegate(UpdateDelegateMethod);
39        sj.Attach(new UpdateDelegate(UpdateDelegateMethod));
40        sj.Notify();
41    }

42}

类Subjuect中的委托(UpdateDelegate)之前有event关键字,它的IL视图为:

如果我们把委托(UpdateDelegate)之前的event关键字去掉,它的IL视图为:

两幅图对比之下,我们就会发现,加上Event关键之和去掉Event关键字所产生的IL代码大不相同。
我们再来看看Main函数中使用的不同
如果我们去掉委托(UpdateDelegate)之前的event关键字,下边Main方法中的写法都是对的,在编译的时候不会报错。

1    public static void Main(string[] args)
2    {
3        Subject sj = new Subject();
4        sj.UpdateHandler = UpdateDelegateMethod;
5        sj.UpdateHandler = new UpdateDelegate(UpdateDelegateMethod);
6        sj.UpdateHandler += new UpdateDelegate(UpdateDelegateMethod);
7        sj.Attach(new UpdateDelegate(UpdateDelegateMethod));
8        sj.Notify();
9    }

如果我们在委托(UpdateDelegate)之前加上event关键字

 1    public static void Main(string[] args)
 2    {
 3        Subject sj = new Subject();
 4        //加上event关键字,下边两段代码要报错
 5        //事件“Subject.UpdateHandler”只能出现在 += 或 -= 的左边(从类型“Subject”中使用时除外)
 6        //sj.UpdateHandler = UpdateDelegateMethod;
 7        //sj.UpdateHandler = new UpdateDelegate(UpdateDelegateMethod);
 8        sj.UpdateHandler += new UpdateDelegate(UpdateDelegateMethod);
 9        sj.Attach(new UpdateDelegate(UpdateDelegateMethod));
10        sj.Notify();
11    }

C#中,delegate是multicast的。multicast就是delegate可以同时指向多个函数。一个multicast   delegate维护着一个函数的list,如果我们没有用+=,而是直接把函数指派给了delegate,这样的话,其他已经钩上delegate的函数都被去掉了,从这里我们就可以看出,使用event可以防止我们直接把函数指派给delegate,从机制上保证了delegate函数链不被破坏。

抱歉!评论已关闭.