Events are treated within metadata much like Properties; that is, as a way to associate a collection of methods defined on a given class. There are two required methods (add_
and remove_
) plus an optional one (raise_
); additonal methods with other names are also permitted (§18). All of the methods gathered together as an Event shall be defined on the class (§I.8.11.4)
The association between a row in the TypeDef table and the collection of methods that make up a given Event is held in three separate tables (exactly analogous to the approach used for Properties), as follows:
Row 3 of the EventMap table indexes row 2 of the TypeDef table on the left (MyClass
), whilst indexing row 4 of the Event table on the right (the row for an Event called DocChanged
). This setup establishes that MyClass
has an Event called DocChanged
. But what methods in the MethodDef table are gathered together as 'belonging' to event DocChanged
? That association is contained in the MethodSemantics table — its row 2 indexes event DocChanged
to the right, and row 2 in the MethodDef table to the left (a method called add_DocChanged
). Also, row 3 of the MethodSemantics table indexes DocChanged
to the right, and row 3 in the MethodDef table to the left (a method called remove_DocChanged
). As the shading suggests, MyClass
has another event, called TimedOut
, with two methods, add_TimedOut
and remove_TimedOut
.
Event tables do a little more than group together existing rows from other tables. The Event table has columns for EventFlags, Name (e.g., DocChanged
and TimedOut
in the example here), and EventType. In addition, the MethodSemantics table has a column to record whether the method it indexes is an add_
, a remove_
, a raise_
, or other function.
The Event table has the following columns:
-
EventFlags (a 2-byte bitmask of type EventAttributes, §II.23.1.4)
-
Name (an index into the String heap)
-
EventType (an index into a TypeDef, a TypeRef, or TypeSpec table; more precisely, a TypeDefOrRef (§II.24.2.6) coded index) (This corresponds to the Type of the Event; it is not the Type that owns this event.)
Note that Event information does not directly influence runtime behavior; what counts is the information stored for each method that the event comprises. The EventMap and Event tables result from putting the .event directive on a class (§II.18).
This contains informative text only.
-
The Event table can contain zero or more rows
-
Each row shall have one, and only one, owner row in the EventMap table [ERROR]
-
EventFlags shall have only those values set that are specified (all combinations valid) [ERROR]
-
Name shall index a non-empty string in the String heap [ERROR]
-
The Name string shall be a valid CLS identifier [CLS]
-
EventType can be null or non-null
-
If EventType is non-null, then it shall index a valid row in the TypeDef or TypeRef table [ERROR]
-
If EventType is non-null, then the row in the TypeDef, TypeRef, or TypeSpec table that it indexes shall be a Class (not an Interface or a ValueType) [ERROR]
-
For each row, there shall be one
add_
and oneremove_
row in the MethodSemantics table [ERROR] -
For each row, there can be zero or one
raise_
row, as well as zero or more other rows in the MethodSemantics table [ERROR] -
Within the rows owned by a given row in the TypeDef table, there shall be no duplicates based upon Name [ERROR]
-
There shall be no duplicate rows based upon Name, where Name fields are compared using CLS conflicting-identifier-rules [CLS]
End informative text.