说说Delegate和Event

说说Delegate和Event

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函数链不被破坏。
分类: Asp.Net 2.0
绿色通道:好文要顶
关注我
收藏该文
与我联系
王庆
关注 - 0
粉丝 - 2
+加关注
0
0
(请您对文章做出评价)
« 上一篇:说说委托(delegate)
» 下一篇:发布一个日期控件
posted @ 2007-07-20 17:31 王庆 阅读(758) 评论(5) 编辑 收藏


发表评论
 回复 引用 查看 
#1楼2007-07-20 19:30 | 上善若水
你这个关于事件和委托的理解不大对.
Event应当只是一个语法甜头而已,其本质上就是委托.
sj.UpdateHandler = UpdateDelegateMethod
 回复 引用 查看 
#2楼2007-07-20 19:31 | 上善若水
接上
sj.UpdateHandler = UpdateDelegateMethod
这样的方法只是编绎器帮你写了一些代码而已,和委托无根本区别.

 回复 引用 查看 
#3楼2007-07-20 20:03 | 周银辉
" delegate维护着一个函数的list"
有没办法操作这个列表啊?插入,排序....
 回复 引用 查看 
#4楼2007-07-20 21:47 | Adrian.
@周银辉
插入: +=
删除: -=
排序...? 不能直接完成...
但可以迭代获取其中的委托对象
foreach(Delegate del in myDelegate.GetInvocationList())
{
...
}
如下例:
class Program
{
static Action<string> methods;

static void Main(string[] args)
{
methods += print;
methods += printUpper;
methods("asdf");
foreach (Delegate del in methods.GetInvocationList())
{
methods -= (Action<string>)del;
}
Console.WriteLine(methods == null); //True
}

static void print(string a)
{
Console.WriteLine(a);
}

static void printUpper(string a)
{
Console.WriteLine(a.ToUpper());
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值