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.

+3


source to share


3 answers


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.

+5


source


When there is no handler subscribed to MyEvent, MyEvent will be zero. Therefore, before firing an event, first check if there is at least one handler subscribed to it.



+1


source


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.

+1


source







All Articles