添加事件处理程序 - 语法的目的
这是一个有趣的问题,我直到上周与同事进行对话之前从未真正想过。添加事件处理程序 - 语法的目的
当我们添加事件处理程序,我们使用的语法如:
Button1.Click += ClickHandler
至于我可以告诉大家,我们使用+ =同义词“添加”, - =同义词“删除” 。
所以我的问题是,为什么语言创建者选择使用这种语法?为什么不Button1.Click.Add(ClickHandler)?
如果它只是意味着添加,为什么框架创建者不会为List而不是.Add()重载+ =运算符?
我想这是解释在VB.Net中AddHandler和RemoveHandler的存在的相同原因,但我不知道是什么原因。
为什么有添加和删除事件处理程序的特殊语言语法?
非常主观的问题,定义语法的人不会发布到SO,所以在14年前他们的动机需要阅读头脑。无论如何有刺:
事件是一个属性的确切等效。就像属性限制对字段的访问一样,事件限制对委托对象的访问。属性有一个吸气和一个setter。只需要=符号来调用它们。一个就足够了,编译器可以根据属性标识符相对于=符号的位置(左边是setter,右边是getter)来计算setter或getter是否打算。
一个事件有三个访问器:添加,删除和提高。没有在C#中实现Raise(与其他语言不同),所以我们只需要添加和删除的语法。我们不能只使用一个符号来处理属性,位置也没有帮助。添加的最自然的符号是+
,删除的是-
。它在逻辑上(并且在实践中)重新分配底层代理对象,因此它的行为有点像赋值。所以自然的选择是+=
和-=
。
不知道设计者是否遵循了相同的逻辑。 VB.NET设计者当然没有,他们选择语言关键字映射到访问器(AddHandler,RemoveHandler,RaiseEvent)。但C#是语言简洁和绝对最少数量的关键字是强大设计目标的语言。 C++/CLI非常类似于C#,但支持raise访问器,并且根本没有语法糖来创建委托对象。这使得它具有超越C#的能力,它不仅限于使这个代表目标,这是一个名为“unbound delegates”的功能。
最后一点需要注意的是,C#拥有但C++/CLI的委托对象创建语法糖并不重要。因为如果你把它写出来,你会得到这样的代码:
SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(repaintControls);
哪一个bedevils从.NET编程开始的任何程序员的头脑。你必须创建一个新的委托对象以便退订事件???是的你是。糖更容易理解:
SystemEvents.UserPreferenceChanged -= repaintControls;
无论如何编译器会生成相同的代码。也是VB.NET使用关键字的可能原因。
这都是品味的问题。由于类似的原因,Java不允许运算符重载。有些人喜欢阅读文字,有些人喜欢看符号表现形式。
很好的回答!还从Jon Skeet的活动和委托文章中学到了很多:http://csharpindepth.com/Articles/Chapter2/Events.aspx – 2012-04-22 18:27:43