1.A type that defines an event member allows the type (or instances of the type) to notify other objects that something special has happened
2.defining an event member means that a type is offering the following capabilities:
1.A method can register its interest in the event
2.A method can unregister its interest in the event.
3.Registered methods will be notified when the event occurs.
because they maintain a list of the registered methods. When the event occurs, the type notifies all of the registered methods in the collection
3.The common language runtime’s (CLR’s) event model is based on delegates.
A delegate is a typesafe way to invoke a callback method.
Callback methods are the means by which objects receive the notifications they subscribed to.
示例:
the application initializes by constructing an instance of MailManager.
MailManager offers a NewMail event. When the Fax and Pager
objects are constructed, they register an instance method with MailManager’s NewMail event so that
MailManager knows to notify the Fax and Pager objects when new email messages arrive.
Now,when MailManager receives a new email message (sometime in the future), it will raise the NewMail event, giving all of the registered methods an opportunity to process the new message in any way they want.
1.Designing a Type That Exposes an Event
steps:
1.Define a type that will hold any additional information that should be sent to receivers of the event notification
This additional information needs to be encapsulated into its own class, which typically contains a bunch of private fields along with some read-only public properties to expose these fields.
By convention, classes that hold event information to be passed to the event handler should be derived from System.EventArgs, and the name of the class should be suffixed with EventArgs.
2.Define the event member
using the C# keyword event.
Each event member is given accessibility(which is almost always public so that other code can access the event member),a type of delegate indicating the prototype of the method(s) that will be called
a name (which can be any valid identifier)
NewMail is the name of this event. The type of the event member is EventHandler<NewMailEventArgs>, which means that all receivers of the event notification must supply a callback method whose prototype matches that of the EventHandler<NewMailEventArgs> delegate type.
Because the generic System.EventHandler delegate is defined as follows.
public delegate void EventHandler<TEventArgs>(Object sender, TEventArgs e);
the method prototypes must look like the following.
void MethodName(Object sender, NewMailEventArgs e);
3.Define a method responsible for raising the event to notify registered objects that the event has occurred
By convention, the class should define a protected
virtual method that is called by code internally within the class and its derived classes when the event is to be raised.
This method takes one parameter,a NewMailEventArgs object, which includes the information passed to the objects receiving the notification.
优化:define an extension method that encapsulates this thread-safety logic
A class that uses MailManager as a base type is free to override the OnNewMail method.
This capability gives the derived class control over the raising of the event. The derived class can handle
the new email message in any way it sees fit.
Usually, a derived type calls the base type’s OnNewMail method so that the registered method(s) receive the notification. However, the derived class might decide to disallow the event from being forwarded.
4.Define a method that translates the input into the desired event
其他知识点:
1.The EventArgs class is defined in the Microsoft .NET Framework Class Library (FCL)
this type is nothing to write home about. It simply serves as a base type from which other types can derive.
Many events don’t have any additional information to pass on.just use EventArgs.Empty rather than constructing a new EventArgs object.
2.why the event pattern requires the sender parameter to always be of type Object?
(1) the cast is required, so the sender parameter might as well be typed as Object.like
void MethodName(MailManager sender, NewMailEventArgs e);
(2)typing the sender parameter as Object is just flexibility.
It allows the delegate to be used by multiple types that offer an event that passes a NewMailEventArgs object.
this is to add additional consistency to the pattern, making it easier for developers to learn and implement the pattern
the EventArgs-derived parameter e.
that spit out source code (such as Microsoft Visual Studio) also know to call the parameter e.
(3)the event pattern requires all event handlers to have a return type of void.
way to get the return values from all of them.
the callbacks to return a value.
it returns an object of type Assembly.
(4)Raising an Event in a Thread-Safe Way
the chain making NewMail null, resulting in a NullReferenceException being thrown
优化:理论正确,但编译器优化之后还是错误的
this is why this technique works in theory.
this code could be optimized by the compiler to remove the local temp variable entirely.
is still possible.
优化:真正正确
really has to be copied to the temp variable now.
not null.
knows not to optimize away the local temp variable.
reference in a local variable ensures that the heap reference is accessed only once.
safety is not an issue anyway.
method will be invoked after it has been removed from the event’s delegate chain.
2.How the Compiler Implements an Event
public event EventHandler<NewMailEventArgs> NewMail;
compiling
1.head of a list of delegates that will be notified when this event occurs.
meaning that no listeners have registered interest in the event
original line of source code defines the event as public.to prevent code outside the defining class from manipulating it improperly
2.type; the event’s collection of methods remains unchanged.
3.thread-safe way
4.the delegate field directly
6.entry into the managed assembly’s metadata.
delegate type, and refers to the add and remove accessor methods.
simply to draw an association between the abstract concept of an “event” and its accessor methods.
Compilers and other tools can use this metadata
the System.Reflection.EventInfo class.
information and requires only the accessor methods at run time.
3.Designing a Type That Listens for an Event
that uses an event provided by another type
1. the reference to the MailManager object as a parameter
2.mm.NewMail += FaxMsg;
compiling
mm.add_NewMail(new EventHandler<NewMailEventArgs>(this.FaxMsg));
delegate object that wraps the Fax class’s FaxMsg method
3.an event, the object can’t be garbage collected.
method, the implementation should cause it to unregister interest in all events
4.from the list.
CS0571 cannot explicitly call operator or accessor error message.
4.Explicitly Implementing an Event
原因:
events!
would be wasted for each object created from a Control-derived type
type also offer many events that most programmers do not use.
delegates.
1.
(1).When the object needs to raise an event, the event identifier is looked up in the collection.
associated with the event identifier is invoked.
of the developer who is designing the type that defines the events;
no idea how the events are implemented internally.
2.object, and each of this class’s events is explicitly implemented
3.normal syntax.
其他知识:
1.the same thing as my EventSet class.
use the FCL’s EventHandlersStore type if you’d like.
offer any thread-safe way to access the events;
thread-safe wrapper around the EventHandlersStore collection if you need to do this.