Event decryption and event decryption

Source: Internet
Author: User
Tags reflector

Event decryption and event decryption

In the previous article, I wrote about delegation. I also said that delegation is the basis of many features in C #. The event to be discussed in this article is based on delegation. In C #1.0, delegation and events are the two most important features.

1. What is an event?

Event design involves two types of roles: Event publisher and event subscriber. When an event occurs, the event publisher publishes a message. The event subscriber receives the information and processes it accordingly. This is the process of the event.

 

2. Use Events

2.1 define events

In C #, defining events is similar to defining class members. You only need an event keyword. For example:

Public event EventHandler birthday;

Event is the keyword, and EventHandler is the delegate type.

Therefore, the structure defined by the event can be summarized as: the access modifier event Delegate type event name. The delegate type can be a custom delegate type or.. NET class library pre-defined delegation type EventHandler.

2.2 subscription and cancellation events

The event subscriber needs to subscribe to the event message published by the event publisher so that the event can receive and handle the message in a triggered manner. In C #, you can use "+ =" to subscribe to events and use "-=" to unsubscribe to events.

Public class Bridegroom
{
// Custom delegate
Public delegate void MarryHandler (string msg );
// Use a custom delegate type to define an event named MarryEvent
Public event MarryHandler MarryEvent;

// Issue the event
Public void OnMarriageComing (string msg)
{
// Determine whether an event handling method is bound
If (MarryEvent! = Null)
{
// Trigger the event
MarryEvent (msg );
}
}


Static void Main (string [] msg)
{
Bridegroom bridegroom = new Bridegroom ();

// Instantiate a friend object
Friend friend1 = new Friend ("James ");
Friend friend2 = new Friend ("Li Si ");
Friend friend3 = new Friend ("Wang Wu ");

// Use "+ =" to subscribe to events
Bridegroom. MarryEvent + = new MarryHandler (friend1.SendMessage );
Bridgeroom. MarryEvent + = new MarryHandler (friend2.SendMessage );

// Send a notification. Only the objects that have subscribed to the event can receive the notification.
Bridegroom. OnMarriageComing ("Friend, I Will Marry !! ");
Console. WriteLine ("------------------------------------");

// Use "-=" to cancel event subscription. At this time, Li Si will not receive the notification
Bridegroom. MarryEvent-= new MarryHandler (friend2.SendMessage );

Bridegroom. MarryEvent + = new MarryHandler (friend3.SendMessage );

Bridegroom. OnMarriageComing ("Friend, I Will Marry !! ");

Console. ReadKey ();
}
}

Public class Friend
{
Public string Name;
Public Friend (string name)
{
Name = name;
}
// Event processing function, which must comply with the definition of the MarryHandler delegate
Public void SendMessage (string message)
{
Console. WriteLine (message );
Console. WriteLine (this. Name + "received, attend on time ");
}
}

It is worth noting that the definition of the event processing function must be consistent with the custom delegate definition, that is, the number of parameters, parameter type and return type must be the same as that of the delegate.

In addition to customizing the delegate type to define events, you can also use the pre-defined delegate type EventHandler in the. NET class library to define events. Pay attention to their parameters.

Public class Bridegroom
{
// Use the type definition event in the. NET class library. The event name is MarryEvent.
Public eventEventHandlerMarryEvent;

// Issue the event
Public void OnMarriageComing (string msg)
{
// Determine whether an event handling method is bound
If (MarryEvent! = Null)
{
Console. WriteLine (msg );
// Trigger the event
MarryEvent (this, new EventArgs ());
}
}


Static void Main (string [] msg)
{
Bridegroom bridegroom = new Bridegroom ();

// Instantiate a friend object
Friend friend1 = new Friend ("James ");
Friend friend2 = new Friend ("Li Si ");
Friend friend3 = new Friend ("Wang Wu ");

// Use "+ =" to subscribe to events
Bridegroom. MarryEvent + = new MarryHandler (friend1.SendMessage );
Bridgeroom. MarryEvent + = new MarryHandler (friend2.SendMessage );

// Send a notification. Only the objects that have subscribed to the event can receive the notification.
Bridegroom. OnMarriageComing ("Friend, I Will Marry !! ");
Console. WriteLine ("------------------------------------");

// Use "-=" to cancel event subscription. At this time, Li Si will not receive the notification
Bridegroom. MarryEvent-= new MarryHandler (friend2.SendMessage );

Bridegroom. MarryEvent + = new MarryHandler (friend3.SendMessage );

Bridegroom. OnMarriageComing ("Friend, I Will Marry !! ");

Console. ReadKey ();
}
}

Public class Friend
{
Public string Name;
Public Friend (string name)
{
Name = name;
}
// Event processing function, which must comply with the definition of the MarryHandler delegate
Public void SendMessage (Object s, EventArgs e)
{
Console. WriteLine (this. Name + "received, attend on time ");
}
}

EventHandler is a pre-defined delegate type in the. NET class library. It is used to process events that do not contain event data. Use Reflector to view the EventHandler definition:

[Serializable, ComVisible(true), __DynamicallyInvokable]public delegate void EventHandler(object sender, EventArgs e);

It can be seen from the definition that the return type of the delegate type is void, and the first parameter sender is responsible for saving the reference of the trigger event object, whose type is object; the second parameter e is used to save event data. The EventArgs class is also defined in the. NET class library. It does not store any data. To include event data in an event, you must use the EventArgs derived class.

2.3 extended EventArgs class

As mentioned above, to include event data in an event, you must use the derived class of EventArgs. The specific implementation code is as follows:

Public class MarryEventArgs: EventArgs
{
Public string Message;
Public MarryEventArgs (string msg)
{
Message = msg;
}
}

Public class Bridegroom
{
// Customize the delegate type. The delegate contains two parameters.
Public delegate void MarryHandler (Object sender, MarryEventArgs e);
// Use a custom delegate type to define an event named MarryEvent
Public event MarryHandler MarryEvent;
// Issue the event
Public void OnMarriageComing (string msg)
{
// Determine whether an event handling method is bound
If (MarryEvent! = Null)
{
// Trigger the event
      MarryEvent (this, new MarryEventArgs (msg ));
}
}


Static void Main (string [] msg)
{
Bridegroom bridegroom = new Bridegroom ();
// Instantiate a friend object
Friend friend1 = new Friend ("James ");
Friend friend2 = new Friend ("Li Si ");
Friend friend3 = new Friend ("Wang Wu ");
// Use "+ =" to subscribe to events
Bridegroom. MarryEvent + = new MarryHandler (friend1.SendMessage );
Bridgeroom. MarryEvent + = new MarryHandler (friend2.SendMessage );
// Send a notification. Only the objects that have subscribed to the event can receive the notification.
Bridegroom. OnMarriageComing ("Friend, I Will Marry !! ");
Console. WriteLine ("------------------------------------");
// Use "-=" to cancel event subscription. At this time, Li Si will not receive the notification
Bridegroom. MarryEvent-= new MarryHandler (friend2.SendMessage );
Bridegroom. MarryEvent + = new MarryHandler (friend3.SendMessage );
Bridegroom. OnMarriageComing ("Friend, I Will Marry !! ");
Console. ReadKey ();
}
}

Public class Friend
{
Public string Name;
Public Friend (string name)
{
Name = name;
}
// Event processing function, which must comply with the definition of the MarryHandler delegate
Public void SendMessage (Object s, MarryEventArgs e)
{
Console. WriteLine (E. Message);
Console. WriteLine (this. Name + "received, attend on time ");
}
}

The EventArgs class is extended through the custom MarryEventArgs event class. In this case, MarryEventArgs carries an event parameter named Message. Then, in the SendMessage method of the subscription object, e. message to obtain event data and output event data.

 

3. Nature of events

From the above example, we can know that the event is based on the delegate. So what is the relationship between them? This must be done through Reflector.

Simple source code:

Namespace Snoop event nature
{
Class Program
{
Public delegate void MarryHanler (string msg );

Public event MarryHanler MarryEvent;
Static void Main (string [] args)
{
}
}
}

Reflector decompilation result:

Figure 1

 

Figure 2

 

Figure 3

Figure 4

It can be seen that the C # event is compiled into a code segment containing two common methods, one with the add _ prefix and the other with the remove _ prefix. The prefix is followed by the name of the C # event.

In the add _ method, Delegate is called. implemented by the Combine () method (the place in the red box in figure 3), Delegate. the Combine () method combines multiple delegates into one multicast delegate.

The Delegate. remove () method is also used in the Remove _ method.

From the above four figures, we can summarize:

The C # event is a special multi-channel broadcast delegate. By default, the event contains a private delegate type variable (the red box in figure 2), which is used to save reference to the event processing method, the delegate type variables are private and can only be accessed from the class that defines the event.

From the decompiled code, we can see that the attributes we have learned are similar. Unlike events, set accessors and get accessors are defined in properties. The two accessors are essentially two methods prefixed with "get _" and "set. Attribute is used to access private fields in the class, and the C # event can also be considered as "attribute of the delegate field". Therefore, you can access private delegated fields through events, this is also the reason for the existence of C # event features. C # The event mechanism conforms to the object-oriented encapsulation feature, making the code safer.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.