1

在 C# 中,我们像这样附加一个事件处理程序:

form1.Click += new EventHandler(form1_Click);

“加号”的意义是什么?我知道我们可以为一个控件附加许多事件处理程序,因此+=语法是有意义的。但我想我也应该能够写这个:

form1.Click = new EventHandler(form1_Click);

这样我就可以覆盖所有以前的处理程序并仅附加最后一个处理程序,但这不会编译。自然地,我认为+=运算符应该像字符串和整数一样工作。强制 +=处理程序的设计原则是什么?换句话说,为什么我不能只写=

4

5 回答 5

4

事件处理程序在内部由一个委托数组表示,因此适用普通的+=&-=运算符。

但是,您可以使用直接分配的=,但只能在定义事件的类中使用,这将清除所有以前的事件处理程序,替换为您分配的事件处理程序。

于 2012-09-20T04:31:05.140 回答
3

本文中,请查看发布和订阅部分。

在 C# 中,任何对象都可以发布一组其他类可以订阅的事件。当发布类引发事件时,会通知所有订阅的类。

因此,您是订阅者,您不必担心影响已订阅者的列表。这是出版商的能力。

如果您说这取决于程序员,那么您可以开发您的“发布者”类,以便它们可以提供一些公共方法,让任何订阅者有机会重置某些事件订阅。在框架中,它被设计禁止。这也是某些程序员的决定。

于 2012-09-20T04:50:15.737 回答
2

就像是

a += 2

这意味着

a = a + 2

如果我们这样做了

a = 2

这将消除一个值并将其替换为 2。

相似地

form1.Click += new EventHandler(form1_Click);

方法

form1.Click = form1.Click +  new EventHandler(form1_Click);

意味着将我们的事件处理程序添加到 form1.click 之前所做的事情。

现在 form1.Click 会做它默认做的事情,也会做我们希望它在 form1_click 做的事情

如果我们写

form1.Click = new EventHandler(form1_Click);

这将清除所有以前的事件处理程序并仅添加我们的form1_Click

于 2012-09-20T04:30:28.920 回答
2

因为当您event使用event SomeHandler SomeEvent语法定义 , 时,它默认为您定义addandremove。这里的要点是,您公开与 an 交互的唯一event方式是通过addand remove(分别由 和 访问+=-=。该语言不允许“全部重置”操作,这就是=不允许的原因。

为了解决这个“设计选择”这个更潜在的问题......我想驱动力是一个多播模型的合同,订阅者可以自由添加和删除他们的订阅event允许任何人取消订阅所有订阅者将违反该合同,并且只允许一个订阅者不是合同。

附录: 看起来您正在寻找的是直接公开委托的能力,如果您只依赖 .NET 的多播委托语法,就可以做到这一点。它看起来很像event语法,但允许使用 a 进行清除,=甚至足够聪明,可以理解+=a null delegate(见输出):

public delegate void F(int x);

public static void Main()
{
    F f = null;
    f += x => System.Console.WriteLine("First: {0}", x);
    f += x => System.Console.WriteLine("Second: {0}", x);
    f(5);
}

或者,您可以使用长格式eventwith your add/ removehit an internal list 并提供一种允许清除该列表的方法。

于 2012-09-20T04:41:33.973 回答
1

你可以没有,一个或很多,所以你添加一个(订阅)使用+=或以其他方式删除(取消订阅)对面-=

form1.Click += new EventHandler(form1_Click); 
// click here will execute form1_Click
form1.Click += new EventHandler(form1_Click2);
// click here will execute form1_Click1 AND form1_Click2
form1.Click -= new EventHandler(form1_Click1);
// click here will JUST execute form1_Click2

现在,强制使用 += 将阻止开发人员自己动手。我的意思是,能够从任何其他类调用 form1.Click = ... 将使一个用户能够无意中清除其他附加的代表。这就是默认情况下强制执行它的原因。

于 2012-09-20T04:28:31.690 回答