Event Metadata

Event Metadata

To define an event, we need to know the event type, which, as a rule, is derived from [mscorlib]System.MulticastDelegate; the methods associated with the event (methods to subscribe to the event, to unsubscribe, to fire the event, and perhaps to carry out other tasks we might define); and, of course, the class defining the event. Because events are never referenced in IL instructions, we needn’t worry about the syntax for referencing the events.

The event metadata group includes the Event, EventMap, TypeDef, TypeRef, Method, and MethodSemantics tables. Figure 12-2 shows the mutual references between the tables of this group.

Figure 12-2 The event metadata group.

The Event Table

The Event table has the associated token type mdtEvent (0x14000000). An Event record has three entries:

  • EventFlags (2-byte unsigned integer)  Binary flags of the event characteristics.

  • Name (offset in the #Strings stream)  The name of the event, which must be a simple name no longer than 1023 bytes in UTF-8 encoding.

  • EventType (coded token of type TypeDefOrRef)  The type associated with the event.The coded token indexes a TypeDef or TypeRef record. The class indexed by this token is either a delegate or a class providing the necessary functionality similar to that of a delegate.

Only two flag values are defined for events, and only one of them can be set explicitly:

  • specialname (0x0200)  The event is special in some way, as specified by the name.

  • rtspecialname (0x0400)  The event has a special name reserved for the internal use of the common language runtime. This flag can’t be set explicitly. The IL Disassembler (ILDASM) outputs this flag for information purposes, but the IL assembly language (ILAsm) compiler ignores the keyword.

To my knowledge, the primary use of these event flags is to mark deleted events in edit-and-continue scenarios. When an event record is marked as deleted, both flags are set and its name is changed to _Deleted. Some compilers, however, might find certain uses for the specialname flag. After all, an event as a metadata item exists solely for the benefit of the compilers.

The EventMap Table

The EventMap table provides mapping between the classes defining the events (the TypeDef table) and the events themselves (the Event table). An EventMap record has two entries:

  • Parent (record index [RID] to the TypeDef table)  The type declaring the events.

  • EventList (RID to the Event table)  The beginning of the events declared by the type indexed to the Parent entry. The mechanism of addressing the events in this case is identical to the mechanism used by TypeDef records to address the Method and Field records belonging to a certain TypeDef. In the optimized metadata model (the #~ stream), the records in the Event table are ordered by the declaring type. In the unoptimized model (the #- stream), the event records are not ordered and an intermediate lookup metadata table, EventPtr, is used. (The metadata models and intermediate tables are described in Chapter 4, “Metadata Tables Organization.”)

The MethodSemantics Table

The MethodSemantics metadata table connects events and properties with their associated methods and provides information regarding the type of this association. A record in this table has three entries:

  • Semantic (2-byte unsigned integer)  The type of method association.

  • Method (RID to the Method table)  The index of the associated method.

  • Association (coded token of type HasSemantics)  A token indexing an event or a property the method is associated with.

The Semantic entry can have the following values, which look like binary flags but in fact are mutually exclusive:

  • msSetter (0x0001)  The method sets a value of a property.

  • msGetter (0x0002)  The method retrieves a value of a property.

  • msOther (0x0004)  The method has another meaning for a property or an event

  • msAddOn (0x0008)  The method subscribes to an event.

  • msRemoveOn (0x0010)  The method removes the subscription to an event.

  • msFire (0x0020)  The method fires an event.

The same method can be associated in different capacities with different events or properties. An event must have one subscribing method and one unsubscribing method. These methods return void and have one parameter of the same type as the event’s associated type (the EventType entry of the respective Event record). The Microsoft Visual C# .NET and Visual Basic .NET compilers use uniform naming for subscribing and unsubscribing methods: add_<event_name> and remove_<event_name>, respectively. In addition, these compilers mark these methods with the specialname flag.

An event can have at most one firing method. The firing method usually boils down to an invocation of the delegate implementing the event. The Visual C# .NET and Visual Basic .NET compilers, for example, never bother to define a firing method for an event—that is, the method invoking the delegate is there, but it is never associated with the event as a firing method. Such an approach contains a certain logic: the firing method is a purely internal affair of the event publisher and need not be exposed to the event subscribers. And because the compilers, as a rule, use the event metadata to facilitate subscription and unsubscription, associating a firing method with an event is not necessary. If an event does have an associated firing method, however, this method must return void.



Inside Microsoft. NET IL Assembler
Inside Microsoft .NET IL Assembler
ISBN: 0735615470
EAN: 2147483647
Year: 2005
Pages: 147
Authors: SERGE LIDIN

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net