Events are declared inside types with the .event directive; there are no global events.
See Partition II, section 21.13.
In typical usage, the <typeSpec> (if present) identifies a delegate whose signature matches the arguments passed to the event's fire method. The event head may contain the keywords specialname or rtspecialname. specialname marks the name of the property for other tools, while rtspecialname marks the name of the event as special for the runtime. RATIONALE There are currently no event names that are required to be marked with rtspecialname. It is provided for extensions, future standardization, and to increase consistency between the declaration of events and methods (instance and type initializer methods shall be marked with this attribute).
The .addon directive specifies the add method, and the <typeSpec> defaults to the same type as the event. The CLS specifies naming conventions and consistency constraints for events, and requires that the definition of the add method be marked with specialname. The .removeon directive specifies the remove method, and the <typeSpec> defaults to the same type as the event. The CLS specifies naming conventions and consistency constraints for events, and requires that the definition of the remove method be marked with specialname. The .fire directive specifies the fire method, and the <typeSpec> defaults to the same type as the event. The CLS specifies naming conventions and consistency constraints for events, and requires that the definition of the fire method be marked with specialname. An event may contain any number of other methods specified with the .other directive. From the point of view of the CLI, these methods are only associated with each other through the event. If they have special semantics, this needs to be documented by the implementer. Events may also have custom attributes (see Partition II, section 20) associated with them, and they may declare source line information. Example (informative): This shows the declaration of an event, its corresponding delegate, and typical implementations of the add, remove, and fire methods of the event. The event and the methods are declared in a class called Counter. // the delegate .class private sealed auto autochar TimeUpEventHandler extends [mscorlib]System.MulticastDelegate { .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed {} .method public hidebysig virtual instance void Invoke() runtime managed {} .method public hidebysig newslot virtual instance class [mscorlib]System.IAsyncResult BeginInvoke(class [mscorlib]System.Asyn cCallback callback, object 'object') runtime managed {} .method public hidebysig newslot virtual instance void EndInvoke(class [mscorlib]System.IAsyncResult result) runtime managed {} } // the class that declares the event .class public auto autochar Counter extends [mscorlib]System.Object { // field to store the handlers, initialized to null .field private class TimeUpEventHandler timeUpEventHandler // the event declaration .event TimeUpEventHandler startStopEvent { .addon instance void add_TimeUp(class TimeUpEventHandler 'handler') .removeon instance void remove_TimeUp(class TimeUpEventHandler 'handler') .fire instance void fire_TimeUpEvent() } // the add method, combines the handler with existing delegates .method public hidebysig virtual specialname instance void add_TimeUp(class TimeUpEventHandler 'handler') { .maxstack 4 ldarg.0 dup ldfld class TimeUpEventHandler Counter::TimeUpEventHandler ldarg 'handler' call class[mscorlib]System.Delegate [mscorlib]System.Delegate:: Combine(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate) castclass TimeUpEventHandler stfld class TimeUpEventHandler Counter::timeUpEventHandler ret } // the remove method, removes the handler from the multicast delegate .method virtual public specialname void remove_TimeUp(class TimeUpEventHandler 'handler') { .maxstack 4 ldarg.0 dup ldfld class TimeUpEventHandler Counter::timeUpEventHandler ldarg 'handler' call class[mscorlib]System.Delegate [mscorlib]System.Delegate:: Remove(class [mscorlib]System.Delegate, class [mscorlib]System.Delegate) castclass TimeUpEventHandler stfld class TimeUpEventHandler Counter::timeUpEventHandler ret } // the fire method .method virtual family specialname void fire_TimeUpEvent() { .maxstack 3 ldarg.0 ldfld class TimeUpEventHandler Counter::timeUpEventHandler callvirt instance void TimeUpEventHandler::Invoke() ret } } // end of class Counter
|