Events aren't fields - I don't get it

后端 未结 5 1842
清酒与你
清酒与你 2020-12-23 19:22

In C# in depth (an excellent book thus far), Skeet explains events aren\'t fields. I read this section many times and I don\'t understand why the distinction makes

5条回答
  •  情话喂你
    2020-12-23 20:11

    Let's consider the two ways to declare events.

    Either you declare an event using an explicit add/remove method, or you declare an event without such methods.

    In other words, you declare the event like this:

    public event EventHandlerType EventName
    {
        add
        {
            // some code here
        }
        remove
        {
            // some code here
        }
    }
    

    or you declare it like this:

    public event EventHandlerType EventName;
    

    The thing is, in some ways they're the same thing, and in other ways, they're completely different.

    From the perspective of outside code, that is ... code outside of the class publishing the event, they're the exact same thing. To subscribe to an event, you call a method. To unsubscribe, you call a different method.

    The difference is that in the second example code above, those methods will be provided by the compiler for you, however, that's still how it's going to be. To subscribe to the event, you call a method.

    The syntax to do so, in C#, however, is the same, you do either:

    objectInstance.EventName += ...;
    

    or:

    objectInstance.EventName -= ...;
    

    So from the "outside perspective", the two ways are no different at all.

    However, inside the class, there is a difference.

    If you try to access the EventNameidentifier inside the class, you're actually referring to the field that backs the property, but only if you use the syntax that doesn't explicitly declare an add/remove method.

    A typical pattern is like this:

    public event EventHandlerType EventName;
    
    protected void OnEventName()
    {
        var evt = EventName;
        if (evt != null)
            evt(this, EventArgs.Empty);
    }
    

    In this case, when you're referring to EventName, you're actually referring to the field that holds the delegate of type EventHandlerType.

    However, if you've explicitly declared the add/remove methods, referring to the EventName identifier inside the class will be just like outside of the class, since the compiler cannot guarantee that it knows the field, or any other mechanism, in which you store the subscription.

提交回复
热议问题