0

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

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

Button1.Click += ClickHandler

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

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

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

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

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

4

2 回答 2

3

非常主观的问题,定义语法的人不会在 SO 上发帖,所以需要读心术来猜测他们 14 年前的动机。无论如何都要尝试一下:

事件与属性完全等价。就像属性限制对字段的访问一样,事件限制对委托对象的访问。一个属性有一个 getter 和一个 setter。调用它们只需要 = 符号。一个就足够了,编译器可以从属性标识符相对于 = 符号的位置(左边是 setter,右边是 getter)来判断 setter 还是 getter。

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

不知道设计师是否真的遵循相同的逻辑。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 使用关键字的可能原因。

于 2012-04-22T10:02:00.827 回答
0

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

于 2012-04-22T05:39:36.430 回答