[C # Basic Knowledge Series] Topic 2: The Essential Theory of Commission

introduction:

The last topic has shared with you what I understand-why delegation is required in C #. The topic briefly introduces what the next delegation is and the simple application of the delegation. In this topic, the delegation will be further introduced. This topic Mainly discuss the nature of the commission and the chain of delegation.

1. The nature of the commission

  Usually we are very easy to use the delegate-use the C # delegate keyword to define the delegate, and then use the new operator to construct the delegate instance, and then call the callback method by calling the delegate instance (that is, using a variable of the delegate object to replace the method name, this sentence If the person you just contact is not easy to understand, here is an example: MyDelegate mydelegate = new Mydelegate (obj.mymethod), MyDelegate is a delegate defined, assuming that there is no parameter defined, and then call the delegate instance like this— —Mydelegate (), you can find that the method of calling the delegate and the method is exactly the same at this time . If you do n’t see mydelegate is a delegate type, everyone will think that this is a direct method call, not a delegate instance . Through this example, everyone It should be easy to understand this sentence-use a variable of the delegate object to replace the method name), I believe that after the explanation in parentheses, I believe everyone will have a further understanding of the delegate-the delegate is the replacement of the method Product, the delegate variable is now named method, you can simply De-commission is a "nickname" approach.

  The previous ones introduce some of the use and understanding of delegation. Now let me take a closer look at what the compiler and CLR have done behind the delegation type defined by the delegate keyword. In the previous topic, I I have said that the delegate is a class, so this is valid, because when we define a delegate type in the IDE, we finally convert the defined code into the intermediate language IL through the compiler , and then execute the code in the intermediate language. It is converted into native code, so the code written in Visual Studio is just a wrapper, and the real program executes the code in the intermediate language. Now let's see what kind of intermediate language code the compiler converts the delegate type we defined into.

  When we define a delegate in the class like this:

public delegate void DelegateTest(int parm);

  The compiler compiles the delegate type we defined into a class like this:

Copy code
Public class DelegateTest: System.MulticastDelegate {         public DelegateTest(Object object, IntPtr method);          public virtual Void Invoke(int32 parm);           public virtual IAsyncResult BeginInvoke(Int32 parm, AsyncCallback callback, Object object );            public virtual void EndInvoke(IAsyncResult result);  }
Copy code

  From the code of the intermediate language, it can be clearly seen that the delegate we wrote in the code is a class for the intermediate language. This class inherits the Systme.MulticastDelegate type defined in the FCL . All delegate types are derived from MulticastDelegate. There are also four methods defined in this class, a constructor , Invoke method , and two asynchronous methods, BeginInvoke and EndInvoke methods. For these two asynchronous methods, you can check the thread series in my blog. You can use the ILDasm.exe tool to view the intermediate code generated by the commission. Below is a picture I cut ( the icon in front of the DelegateTest we defined is the same as the icon of the Program passed by our main program , but Program is a class, very Obviously defined delegate DelegateTes is also a class):

  Since all delegate types are inherited from MulticastDelegate , MulticastDelegate inherits from Delegate, so the delegate type inherits the fields, properties, and methods of MulticastDelegate. Among these members, there are three non-public fields related to the delegate chain to be introduced in the following topic, so Listed here first:

Field

Types of

Explanation

_target

System.Object

When the delegate object wraps a static method, this field is null. When the delegate object wraps an instance method, this field refers to the object of the class in which the method resides

_methodPtr

System.IntPtr

An internal integer, which can be considered as a method handle, identifies the method to be called  

_invocationList

System.Object

This field is usually null. When constructing a delegation chain (multicast delegation), a delegation array is referenced. Explain in the next part.

  Most people may have such a question. Since it is a non-public field, it is not visible on MSDN. How do I know there are these three fields? You can use the Reflector tool to decompile to view the source code. The Multicastdelegate class can be found by MSDN. You can know the namespace and assembly of the class, so that you can use the Reflector tool to view the source code of the Multicastdelegate class. Screenshot of the source code viewed by Reflector :

  It can be seen from the screenshot that there are only two fields in the MulticastDelegate class, but there are no _ methodPtr and _ target fields listed in the previous table . These two fields are defined in the Delegate class. You can use the Reflector tool to view it, here No specific stickers, the article will give the Reflector tool download link.

 The delegate object is a wrapper that wraps a method and the object to be operated when the method is called, for example, when the following code is executed:

Copy code
  public   class Program {        // Declare a delegate type, its instance refers to a method        // This method returns an int parameter, and returns a void type        public  delegate  void DelegateTest ( int parm);         public  static  void Main ( string [] args) {             / / Use a static method to instantiate the delegate             DelegateTest dtstatic = new DelegateTest (Program.method1);             // Use an instance method to instantiate the delegate             DelegateTest dtinstance = new DelegateTest ( new Program (). Method2);}         private  static  voidmethod1 ( int parm) {Console.WriteLine ( " The static method is called, the parameter value is: " + parm);}         private  void method2 ( int parm) {Console.WriteLine ( " The instance method is called, the parameter value is: " + parm);}}
Copy code

  The dtstatic and dtinstance variables in the code refer to the initialized DelegateTest delegate objects. At this time, the initialization of the three fields listed above for these two delegate objects is as follows:

2. Summary

This topic from the perspective of the intermediate language to analyze in detail how the defined intermediate type converted by the compiler to explain a delegate type, the conclusion is-the delegate is actually a class , which is derived from MulticastDelegate Class, and inherits the three fields _target, _methodPtr, and _invocationList of the class. When we initialize a delegate object, we will initialize these three fields first. For the delegation of wrapping instance methods and static methods, initialize These three fields are also different, as shown in the screenshot above. A very important field is quoted here-_invocationList (that is, the call list of the delegate instance). This field is null when the delegate object wraps a method. If the delegate object wants to wrap multiple methods, the _invocationList field will be initialized to refer to an array of delegate objects (that is, a collection pointing to the delegate object). The specific content will be introduced in the next topic. Detailed introduction for everyone. At this point, the content of this topic is also over. I hope that through this topic, you can further understand the delegation in C #.

 

 The download address of the Reflector tool: http://files.cnblogs.com/zhili/Reflector.zip  . If you find it helpful after reading it, please recommend it. Thank you for your support.

Published 28 original articles · Like 15 · Visits 110,000+

Guess you like

Origin blog.csdn.net/z3h0a5n8g8x9i9a2o3/article/details/8603646