Reputation: 73283
In C# we attach an event handler like this:
form1.Click += new EventHandler(form1_Click);
What is the significance of the "plus" sign? I know we can attach many eventhandlers for a control and hence the +=
syntax makes sense. But I think I should also be able to write just this:
form1.Click = new EventHandler(form1_Click);
so that i can override all the previous handlers and attach only the last one, but that wouldnt compile. Naturally I think +=
operator should work as if it is for strings and ints. What is the design principle for forcing +=
for handlers? In other words why cant i write just =
?
Upvotes: 1
Views: 171
Reputation: 18553
In this article, please, have a look at Publishing and Subscribing section.
In C#, any object can publish a set of events to which other classes can subscribe. When the publishing class raises an event, all the subscribed classes are notified.
So, you are a subscriber, you are not concerned to influence the list of those, who has already subscribed. It's in the publishers competence.
If you say it's up to a programmer, than you could develop your "publisher"-classes so that they could provide some public method, giving an opportunity to any subscriber to reset some event subscription. In the framework it is prohibited by design. This is also a decision by certain programmers.
Upvotes: 3
Reputation: 27683
Because when you define an event
, with the event SomeHandler SomeEvent
syntax, it default-defines add
and remove
for you. The point here is that the only way you publicly interact with an event
is through add
and remove
(accessed by +=
and -=
, respectively). The language does not allow a "reset all" action, which is why =
is not allowed.
To address the more underlying question of a "design choice" for this...I suppose the driving force is that the contract of an event
-- a multicast model where subscribers are free to add and remove their subscriptions. Allowing anyone to unsubscribe all subscribers would go against that contract and allowing only one subscriber isn't the contract.
Addendum:
It looks like what you're looking for is the ability to expose the delegate directly, which can be done if you just rely on .NET's multicast delegate syntax. It looks a lot like the event
syntax, but allows for clearing with =
and is even smart enough to understand +=
on a null
delegate
(see output):
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);
}
Alternatively, you could use the long form of event
with your add
/remove
hitting an internal list and provide a method that allows for clearing that list.
Upvotes: 2
Reputation: 15577
You can have none, one or a lot of them, so you add one (subscribe) using +=
or otherwise remove (unsubscribe) with the 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
Now, enforcing the use of += will be preventing the developer from shooting her own foot. I mean, making able to call form1.Click = ... from any other class will enable one user to clear other attached delegates unintentionally. That's why it's enforced by default.
Upvotes: 1
Reputation: 117175
Event handlers are represented internally by an array of delegates so the normal +=
& -=
operators apply.
You can, however, use direct assigned with the =
, but only within the class that defines the event, and this will wipe out all previous event handlers replacing with the one you're assigning.
Upvotes: 4
Reputation: 48600
Its like
a += 2
that means
a = a + 2
if we did
a = 2
That would wipe out a value and replace it with 2.
similarly
form1.Click += new EventHandler(form1_Click);
means
form1.Click = form1.Click + new EventHandler(form1_Click);
Means add our eventhandler to what form1.click was doing earlier.
Now form1.Click will do what it does by default and also do what we want it to do in form1_click
If we wrote
form1.Click = new EventHandler(form1_Click);
This will wipeout all previous event handlers and add only our form1_Click
Upvotes: 2