说说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());
}
}
说说Delegate和Event
最新推荐文章于 2024-07-08 18:03:54 发布