Events are not fields - I do not understand

In C # in depth (a great book so far), Skeet explains that events are not fields. I have read this section many times, and I do not understand why the difference has any meaning.

I am one of those developers who confuse events and delegate instances. In my opinion, they are the same. Isn't that just a form of indirection? We can multicast. The event is configured as a field as abbreviated ... of course. But we add or remove handlers. Stacking them for a call when an event is triggered. Aren't we doing the same with delegates, folding them up, and calling out a challenge?

+52
c # events field
Apr 28 '12 at 20:11
source share
5 answers

The other answers are mostly correct, but here is another way to look at this:

I am one of those developers who confuse events and delegate instances. In my opinion, they are the same.

An old saying comes to mind not to see a forest for trees. The difference that I make is that events are at a higher "semantic level" than the delegate instance field. The event tells the consumer a type of "hello there, I am the type who likes to tell you when something happens." Type of event source; this is part of his public contract.

How, as an implementation detail, this class chooses to keep track of who is interested in listening to this event, and what and when to tell subscribers that the event is happening is the business of this class. This usually happens with a multicast delegate, but that’s implementation detail. This is such a general implementation detail that it is reasonable to mix the two, but we really have two different things: an open surface and a private implementation.

Similarly, properties describe the semantics of an object: the customer has a name, so the Customer class has the Name property. You can say that "their name" is the property of the client, but you will never say that "their name" is the field of the client; that is a detail of the implementation of a particular class, and not a fact about business semantics. The fact that a property is usually realized as a field is a particular detail of class mechanics.

+47
Apr 29 2018-12-12T00:
source share
— -

Properties are also not fields, although they look like them. This is actually a pair of methods (getter and setter) with special syntax.

Events similarly represent a pair of methods (signed and unsubscribed) with special syntax.

In both cases, you usually have a private “support field” inside your class that contains the value processed by the getter / setter / subscribe / unsubscribe methods. And there is an automatically implemented syntax for both properties and events when the compiler creates a support field and access methods for you.

The goal is also the same: properties provide limited access to the field where some validation logic is executed before saving the new value. And the event provides limited access to the delegate field, where users can subscribe or unsubscribe, rather than reading the list of subscribers and not replacing the entire list at once.

+41
Apr 28 '12 at 20:12
source share

Consider two ways to declare events.

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

In other words, you are declaring an event as follows:

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

or declare it as follows:

 public event EventHandlerType EventName; 

The fact is that in a sense this is one and the same, and in other respects they are completely different.

From the point of view of external code, that is ... code outside the class publishing the event is the same. To subscribe to an event, you call a method. To unsubscribe, you call another method.

The difference is that in the second example above, these methods will be provided by the compiler for you, however, that doesn’t matter how it is. To subscribe to an event, you call a method.

The syntax for this, in C #, however, is the same, you also:

 objectInstance.EventName += ...; 

or

 objectInstance.EventName -= ...; 

So, from the “external point of view”, the two methods do not differ at all.

However, there is a difference within the class.

If you try to access the EventName inside the class, you are actually referring to a field that supports the property , but only if you use syntax that does not explicitly declare add / remove .

A typical template is as follows:

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

In this case, when you refer to EventName , you are really referring to a field that contains a delegate of type EventHandlerType .

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

+24
Apr 28 2018-12-12T00:
source share

The event is an accessory for the delegate. Just as a property is an accessory for the field. Using the same utility, it prevents the code from interacting with the delegate object. As the property has get and set accessor, the event has the ability to add and remove access.

It is slightly different from the property if you do not write the add and remove accessory yourself, and then the compiler automatically creates them. Including a private support field that stores the delegate object. Like an automatic property.

You do not often do this, but it is certainly not unusual. The .NET framework does this quite often, for example, Winforms control events are stored in the EventHandlerList and the add / remove manipulators that are listed through its AddHandler () and RemoveHandler () methods. With the advantage that for all events (there are many), only one field in the class is required.

+9
Apr 28 2018-12-12T00:
source share

I can add to the previous answers that delegates can be declared inside the namespace area (outside the class), and events can be declared only inside the class. This is because a delegate is a class!

Another difference is that for events, the only class that can run it is the class. You can subscribe / unsubscribe to it through the class, but cannot start it (unlike delegates). Therefore, perhaps now you can understand why the convention is to wrap it inside protected virtual OnSomething(object sender, EventArgs e) . This means that descendants will be able to redefine the execution of the shooting.

0
May 02 '12 at 10:14
source share



All Articles