首页 新闻 会员 周边 捐助

为什么在.NET中需要事件?

0
悬赏园豆:10 [已解决问题] 解决于 2014-01-11 20:40
    public delegate void MyEventHandler();

    public class TestClass
    {
        private int someValue;

        //private MyEventHandler MyEvent; 
// 如果把下面一行注释掉,而使用上一行的话,其他代码不需改动也能达到同样效果
private event MyEventHandler MyEvent; public void SomeMethod() { for (someValue = 0; someValue < 100; someValue++) { if (someValue%9 == 0) { MyEvent(); } } } public TestClass() { MyEvent += TestClass_MyEvent; } private void TestClass_MyEvent() { Console.WriteLine(""); } }

在上述代码中,如果不使用event关键字而只用委托也能达到同样的效果(如果执行SomeMethod()方法那么屏幕上会输出9个⑨)。那么事件和委托相比多了哪些特点?什么场合下用事件能达到的效果用委托反而达不到的?

飞鸟_Asuka的主页 飞鸟_Asuka | 菜鸟二级 | 园豆:393
提问于:2014-01-11 18:47
< >
分享
最佳答案
0

委托和事件没有可比性,因为委托是类型,事件是对象,因为对于事件来讲,外部只能“注册自己+=、注销自己-=”,外界不可以注销其他的注册者,外界不可以主动触发事件,因此如果用Delegate就没法进行上面的控制,因此诞生了事件这种语法。事件只能add、remove自己,不能赋值。事件只能+=、-=,不能=、不能外部触发事件。

收获园豆:7
wolfy | 老鸟四级 |园豆:2636 | 2014-01-11 19:12

也就是说事件并不是给本类自身用的,而是给关联此类的对象的类使用是吗?

飞鸟_Asuka | 园豆:393 (菜鸟二级) | 2014-01-11 19:54

刚刚翻了下书,发现事件可以通过add/remove方法来增加订阅和取消订阅时的逻辑。但是直接用委托是没有的。这算不算一个必须使用事件的地方呢?

飞鸟_Asuka | 园豆:393 (菜鸟二级) | 2014-01-11 20:24
其他回答(1)
0

你根本没有理解事件的作用,事件相当于一个交互接口,非Interface。

比如你定了一类,这个类是下载文件,文件大小100G,在下载过程中你可以公开一个ProgressChange事件,在这个事件里下下载类会传出当前下载的文件大小。

那么使用你这个类的调用者,如果需要向用户显示进度,它就订阅这个事件,然后,就可以接收到你传过来的进度,如果不需要,它就不用订阅这个事件了。

不知道我讲清楚了没有。

收获园豆:3
空明流光 | 园豆:111 (初学一级) | 2014-01-11 19:05

你上面的代码根本没有使用事件的必要性,所以没法体现事件的作用。

支持(0) 反对(0) 空明流光 | 园豆:111 (初学一级) | 2014-01-11 19:16

@沧海一杰: 对于我上面给出的例子,如果你真正做过并且想过这个问题,你一定会觉得事件是最方便的,因为目前来说实现这个功能没有比事件更合适的了,当然事件的处理也分同步处理和异步处理两种。

支持(0) 反对(0) 空明流光 | 园豆:111 (初学一级) | 2014-01-11 19:18

ProgressChange事件你可以在下载大小每超过一定的值后触发,比如每下载大于1M的内容时,你触发一次。事件还可以反馈信息,比如你可以在事件里传出一个ref参数,外部就可以控制。 比如你在ProgressChange事件中处理,如果下载进度大于100%,你就可以判断下载完成了,然后删除下载。

支持(0) 反对(0) 空明流光 | 园豆:111 (初学一级) | 2014-01-11 19:23

@沧海一杰: 你举的这个例子还是没有到要害上啊。

刚刚翻了下书,发现事件可以通过add/remove方法来增加订阅和取消订阅时的逻辑。但是直接用委托是没有的。这算不算一个必须使用事件的地方呢?

支持(0) 反对(0) 飞鸟_Asuka | 园豆:393 (菜鸟二级) | 2014-01-11 20:24

@飞鸟_Asuka: 直接用委托是可以的啊,不知道你看的是什么书,例子又如何? 想必书上写的是都是标准事件模型吧?即(object sender, EventArgs e)采用两个参数的这种啊,当然你也可以用非标的,就是直接上委托,很多时候为了简单,我在项目中就直接上非标了

支持(0) 反对(0) 空明流光 | 园豆:111 (初学一级) | 2014-01-11 20:39

@沧海一杰: 我看的是《C#揭秘》,仔细读了下委托和事件那一章。里面有讲到使用事件的优点。

不过还是非常感谢你,打这么多字也挺辛苦了

支持(0) 反对(0) 飞鸟_Asuka | 园豆:393 (菜鸟二级) | 2014-01-11 20:41

@沧海一杰: 只有事件具有add/remove。如果在类中声明委托的对象,它是作为字段来处理的

支持(0) 反对(0) 飞鸟_Asuka | 园豆:393 (菜鸟二级) | 2014-01-11 20:46

@沧海一杰: add/remove其实和+=以及-=没什么区别,类似于C++中的运算符重载,关键是你有没有真正用过事件,上面的例子你如果真正写过代码了,而且是写一个完整的很实用的类的话,你就能体会到了。我已经使用事件有七八年了,几乎每天的代码里都有新建与事件有关的类的代码。如果你从来没有用过,只能说你根本没用需求,如果你能花一两个月写一个简陋的迅雷出来,你就有所领悟了。我曾经模仿过一个迅雷花了三个月多,功能除了没有p2p之外,比迅雷功能强大多了,并且提供下载接口,可以在一分钟内建立超过一万个下载任务,对于普通任务,下载速度绝对比迅雷快。代码里事件简直用疯了,当时异步事件问题曾经让我头疼了很久,因为先激发的事件完成时间滞后于后激发的事件,事件同步很麻烦。

支持(0) 反对(0) 空明流光 | 园豆:111 (初学一级) | 2014-01-11 20:50

@沧海一杰: @飞鸟_Asuka: 我打字用五笔,脑子里一想字就出来了,很快的哦。

支持(0) 反对(0) 空明流光 | 园豆:111 (初学一级) | 2014-01-11 20:55
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册