为什么总是在事件处理程序之前出现+号?

时间:2012-09-20 04:26:42

标签: c# event-handling

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

form1.Click += new EventHandler(form1_Click);

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

form1.Click = new EventHandler(form1_Click);

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

5 个答案:

答案 0 :(得分:4)

事件处理程序由一组代表在内部表示,因此正常+=& -=运营商适用。

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

答案 1 :(得分:3)

请在this文章中查看发布和订阅部分。

  

在C#中,任何对象都可以发布一组其他类的事件   可以订阅。当出版课提出一个事件,所有的   订阅的课程会被通知。

因此,您是订阅者,您并不关心影响已订阅者的列表。它位于 publishers 权限中。

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

答案 2 :(得分:2)

就像

a += 2

这意味着

a = a + 2

如果我们做了

a = 2

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

类似地

form1.Click += new EventHandler(form1_Click);

装置

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

意味着将我们的eventhandler添加到form1.click之前做的事情。

现在,form1.Click将默认执行它所做的操作,并在form1_click中执行我们想要的操作

如果我们写了

form1.Click = new EventHandler(form1_Click);

这会清除所有以前的事件处理程序,只添加form1_Click

答案 3 :(得分:2)

因为当您使用event SomeHandler SomeEvent语法定义event时,默认为您定义add and remove。这里的要点是,您与event公开互动的方式是addremove+=和{{1}访问}}, 分别)。该语言不允许“全部重置”操作,这就是不允许-=的原因。

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

<强>附录: 看起来你正在寻找的是直接公开委托的能力,如果你只依赖.NET的多播委托语法就可以做到这一点。它看起来很像event语法,但允许使用event进行清算,并且足够聪明,可以理解= +=上的null(请参阅{ {3}}):

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); } 的长格式与event / add点击内部列表,并提供允许清除该列表的方法。

答案 4 :(得分:1)

你可以没有,一个或很多,所以你使用+=添加一个(订阅)或者使用oposite -=

删除(取消订阅)
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 = ...将使一个用户无意中清除其他附加的委托。这就是默认情况下强制执行的原因。