Reputation: 47
Is there anything wrong with subscribing to event with
MyPopup.CustomPopupPlacementCallback = popupFixCentered;
instead of:
MyPopup.CustomPopupPlacementCallback += popupFixCentered;
For example, if I am changing to different callback from another method I want to make sure I have only one callback subscribed without needing to -= the correct one.
Upvotes: 2
Views: 573
Reputation: 36523
Well, it sounds like you didn't try it. If you did, you would get the following compilation error:
The event 'XXX' can only appear on the left hand side of += or -= (except when used from within the type 'YourClass')
The error is pretty clear: you can only use the +=
and -=
operators on the event.
If you try to assign to the event
from within the class that defines the event, then it will "work". But the reason it appears to be able to assign to an event
in that case is because it's actually not accessing the event. It's accessing an auto-generated private delegate instance that you may not realize is actually there.
Quoting from Chris Burrows' article on the subject:
outside of the class or struct that defines a field-like event E, binding to the name E resolves to the event itself, on which the only legal operation is calling an accessor; inside the class or struct that defines a field-like event E, binding to the name E resolves to the private delegate field.
To understand this, you need to visualize that when you define an event such as:
public event EventHandler MyEvent;
... what you don't see, is that it actually gets translated into something like this (I'm copying this from Jon Skeet's article on events and delegates. Also note that the exact code it gets translated into has changed between versions of C#, so it may be a bit different, but the general idea is the same):
private EventHandler _myEvent;
public event EventHandler MyEvent
{
add
{
lock (this)
{
_myEvent += value;
}
}
remove
{
lock (this)
{
_myEvent -= value;
}
}
}
So when you access MyEvent
from outside the class, you can only invoke the add
and remove
methods through the +=
and -=
operators.
But from within the class, accessing MyEvent
means something different. It actually becomes a reference to that private _myEvent
delegate variable that you can't see, but it is there. Because this is a delegate type, then you can use the assignment (=
) operator on it.
So, to achieve what you want, you could define a public method in the same class that defines the event, and use that method to set your new event handler.
Something like this:
public class MyClass
{
public event EventHandler MyEvent;
public void setSingleEventHandler(EventHandler eventHandler)
{
this.MyEvent = eventHandler;
}
}
But if you are going to do that, then it defeats the purpose of the event
type. If you only want to invoke a single event handler at most at any given time, then defining it this way (without using the event
keyword) makes more sense:
public class MyClass
{
public EventHandler MyEvent { get; set; }
}
References
Jon Skeet article: Delegates and Events
Chris Burrows article: (also check out the rest of the series): Events get a little overhaul in C# 4, Part II: Semantic Changes and +=/-=
Upvotes: 4
Reputation: 676
I just tested it. Yes, you can use the =
operator to assign to an event. (Edit: Apparently only from within the same class)
delegate void Foo();
event Foo bar;
Method()
{
bar = () => { Console.WriteLine("1"); };
bar();
bar = () => { Console.WriteLine("2"); };
bar();
}
Produces the output:
1
2
But if you try to assign from outside the class, it will give you an error.
You can get around this by using a java-style set method:
SetBar(Foo foo)
{
bar = foo;
}
Only time I'd ever recommend java convention for external access of properties :)
Upvotes: 0