添加事件处理程序 - 语法的用途

时间:2012-04-22 05:32:43

标签: c# events

这是一个有趣的问题,在我上周与同事谈话之前,我从未真正考虑过这个问题。

当我们添加事件处理程序时,我们使用如下语法:

Button1.Click += ClickHandler

据我所知,我们使用+ =与“add”同义,而= =与“remove”同义。

所以我的问题是,为什么语言创建者选择使用这种语法?为什么不Button1.Click.Add(ClickHandler)?

如果只是意味着添加,为什么框架创建者不会重载List的+ =运算符而不是.Add()?

我想这也是解释VB.Net中存在AddHandler和RemoveHandler的原因,但我不知道是什么原因。

为什么添加和删除事件处理程序有特殊的语言语法?

2 个答案:

答案 0 :(得分:3)

非常主观的问题,定义语法的人不会发布到SO,所以在14年前,他们需要阅读他们的动机。无论如何都要刺伤它:

事件与财产完全相同。就像属性限制对字段的访问一样,事件限制了对委托对象的访问。酒店设有吸气剂和二传手。只需要=符号来调用它们。一个就足够了,编译器可以判断setter或getter是否来自属性标识符相对于=符号的位置(左边是setter,右边是getter)。

一个事件有三个访问者:添加,删除和提升。在C#中没有实现Raise(与其他语言不同)所以我们只需要添加和删除语法。我们不能只使用一个符号,就像我们可以使用属性,放置没有帮助。添加的最自然符号为+,删除时为-。它在某种程度上也表现为赋值,因为它在逻辑上(并且在实践中)重新分配了底层委托对象。所以自然选择是+=-=

不知道设计师是否遵循相同的逻辑。 VB.NET设计者当然没有,他们选择了语言关键字映射到访问器(AddHandler,RemoveHandler,RaiseEvent)。但是C#是一种语言简洁,绝对最少的关键字是强大的设计目标。 C ++ / CLI与C#非常相似,但支持raise访问器,并且根本没有语法糖来创建委托对象。它赋予它超越C#的功能,它不仅限于将这个作为委托目标,这是一个名为“未绑定委托”的功能。

最后需要注意的是,委托C#具有的对象创建语法糖但C ++ / CLI并不重要。因为如果你把它写出来,你会得到这样的代码:

SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(repaintControls);

从.NET编程开始,任何程序员的思维都会受到困扰。您必须创建委托对象才能取消订阅一个事件???是的你是。糖更容易理解:

SystemEvents.UserPreferenceChanged -= repaintControls;

编译器无论如何都会生成相同的代码。也就是VB.NET使用关键字的可能原因。

答案 1 :(得分:0)

这都是品味问题。 Java不允许运算符重载,原因与您给出的类似。有些人喜欢阅读文字,有些人喜欢看符号表示。