除了语法糖之外,我没有看到使用事件而不是代理的优点.也许我是误会,但似乎事件只是代表的占位符.
你能告诉我差异以及何时使用哪个?有哪些优点和缺点?我们的代码严重依赖于事件,我想深入了解它.
你何时会在事件中使用代表,反之亦然?请在生产代码中说明您对这两者的真实体验.
关键字event
是多播委托的范围修饰符.这与仅声明多播委托之间的实际区别如下:
您可以event
在界面中使用.
对多播委托的调用访问仅限于声明类.行为就好像委托是私有的调用.出于赋值的目的,访问是由显式访问修饰符(例如public event
)指定的.
由于利益的问题,你可以申请+
和-
多播的代表,这是对的基础+=
和-=
语法为代表的组合分配给事件.这三个片段是等效的:
B = new EventHandler(this.MethodB); C = new EventHandler(this.MethodC); A = B + C;
示例二,说明了直接分配和组合分配.
B = new EventHandler(this.MethodB); C = new EventHandler(this.MethodC); A = B; A += C;
示例三:更熟悉的语法.您可能熟悉null的赋值以删除所有处理程序.
B = new EventHandler(this.MethodB); C = new EventHandler(this.MethodC); A = null; A += B; A += C;
与属性一样,事件具有完全没有人使用过的语法.这个:
class myExample { internal EventHandler eh; public event EventHandler OnSubmit { add { eh = Delegate.Combine(eh, value) as EventHandler; } remove { eh = Delegate.Remove(eh, value) as EventHandler; } } ... }
...... 与此完全相同:
class myExample { public event EventHandler OnSubmit; }
在VB.NET使用的相当笨拙的语法中,添加和删除方法更加引人注目(没有运算符重载).
从技术角度来看,其他答案已经解决了这些差异.
从语义角度来看,事件是在满足特定条件时由对象引发的操作.例如,我的Stock类有一个名为Limit的属性,当股票价格达到Limit时它会引发一个事件.此通知是通过事件完成的.是否有人真正关心此事件并订阅它是超出了所有者类的关注.
委托是一个更通用的术语,用于描述类似于C/C++术语中的指针的构造..Net中的所有代表都是多播代理.从语义学的角度来看,它们通常被用作一种输入.特别是,它们是实施战略模式的完美方式.例如,如果我想对对象列表进行排序,我可以为该方法提供比较器策略,以告诉实现如何比较两个对象.
我在生产代码中使用了这两种方法.当满足某些属性时,我的数据对象的吨数会通知.最基本的例子,每当属性发生变化时,都会引发一个PropertyChanged事件(参见INotifyPropertyChanged接口).我在代码中使用了委托来提供将某些对象转换为字符串的不同策略.这个特殊的例子是一个美化的ToString()特定对象类型的实现列表,以便将它显示给用户.
事件是语法糖.它们很美味.当我看到一个事件时,我知道该怎么做.当我看到代表时,我不太确定.
将活动与界面相结合(更多糖)可以制作令人垂涎欲滴的小吃.代表和纯虚拟抽象类不那么开胃.
事件在元数据中标记为这样.这允许Windows窗体或ASP.NET设计器之类的东西将事件与委托类型的纯属性区分开来,并为它们提供适当的支持(特别是在"属性"窗口的"事件"选项卡上显示它们).
与委托类型的属性的另一个区别是用户只能添加和删除事件处理程序,而使用委托类型的属性,他们可以设置值:
someObj.SomeCallback = MyCallback; // okay, replaces any existing callback someObj.SomeEvent = MyHandler; // not okay, must use += instead
这有助于隔离事件订阅者:我可以将我的处理程序添加到事件中,并且您可以将处理程序添加到同一事件中,并且您不会意外地覆盖我的处理程序.