在C#中,我们附加了一个这样的事件处理程序:
form1.Click += new EventHandler(form1_Click);
“加号”的重要性是什么? 我知道我们可以为控件附加许多事件处理程序,因此+=
语法有意义。但我想我也应该写下这个:
form1.Click = new EventHandler(form1_Click);
这样我可以覆盖所有以前的处理程序并仅附加最后一个处理程序,但这不会编译。当然,我认为+=
运算符应该像字符串和整数一样工作。 强制 +=
处理程序的设计原则是什么? 换句话说,为什么我只能写=
?
答案 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
公开互动的仅方式是add
和remove
(+=
和{{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 = ...将使一个用户无意中清除其他附加的委托。这就是默认情况下强制执行的原因。