Internal event design in C #
Just finished reading Jon Skeet's article on events and delegates and got a question.
Let's say in code first, I declare an event
public event EventHandler MyEvent
Then I want to raise it in code in the way
if (MyEvent != null)
Myevent(this,EvtArgs.Empty);
John says that actually MyEvent looks something like this:
private EventHandler _myEvent;
public event EventHandler MyEvent
{
add
{
lock (this)
{
_myEvent += value;
}
}
remove
{
lock (this)
{
_myEvent -= value;
}
}
}
The question is, what actually happens when I compare MyEvent != null
? As I understand it, it actually compares _myEvent
to null
, but I'm not sure.
source to share
If you implement custom add / remove accessors, you won't be able to compare MyEvent
to null in the first place because it will only be an event - it doesn't matter as such, only add / remove accessors. You will need to use your declared field ( _myEvent
in the example above).
You can only compare using the event name, when you use field events, where you end up with (effectively) the field and the event of the same name. (The compiled code shouldn't actually reuse the event name for the field name, but it should look like it did when compiled.)
Note that with this:
if (MyEvent != null)
MyEvent(this,EvtArgs.Empty);
is not thread safe as it MyEvent
can become null between check and call. You must use:
EventHandler handler = MyEvent;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
Also note that the on-field event blocking part is this
now slightly outdated; C # 4 achieves thread safety using a non-blocking locking mechanism.
source to share
Internally, an event is a set of add / remove methods with a support field of type MulticastDelegate. You get this field when you request MyEvent outside of the class and compare this instance to null.
See also this post: How do C # events work behind the scenes?
Edit: Also, as John already pointed out, you don't get the field if you provide add / remove methods yourself.
source to share