C # Delegate (delegate) secrets

Source: Internet
Author: User

A delegate is a type that defines the method signature. When instantiating a delegate, You can associate its instance with any method with a compatible signature. You can call a method by entrusting an instance.

On the surface, the delegate is simple. Use new to construct the delegate instance. Use the variable name of the delegated instance to call the callback function. The reality is that the compiler, CLR, has done a lot of work behind the scenes to hide its complexity. Only by understanding these things behind the scenes can you really master it and use it flexibly.

1. Declare Delegation

 
Namespace delegatedemo {internal delegate void hellocallback (string name); Class program {static void main (string [] ARGs ){}}}

 

View intermediate data through ildasmCode, As shown below

The compiler automatically generates a hellocallback class containing constructor, callback method invoke, and asynchronous callback method (begininvoke, endinvoke ),

It inherits the multicastdelegate class, And multicastdelegate inherits the delegate class. C # has two delegate classes (delegate and multicastdelegate) for a historical reason. It was originally merged into a class, but it was almost release time, merging it requires a retest, so the delegate will survive ).

2. Delegation instantiation

Internal delegate void hellocallback (string name); Class program {static void main (string [] ARGs) {hellocallback helloshow = new hellocallback (showname); console. readline ();} static void showname (string name) {console. writeline (name );}}

 

The intermediate code is as follows:

. Method private hidebysig static void main (string [] ARGs) cel managed
{
. Entrypoint // The first method to be executed is called the entry function.
// Code size 15 (0xf)
. Maxstack 3 // defines the maximum depth of the stack used by function code
. Locals Init ([0] class delegatedemo. hellocallback helloshow) // assign a local variable helloshow

il_0000: NOP // if the operation code is patched, the space is filled and no meaningful operation is performed.

Il_0001: ldnull // push the null reference to the computing Stack
Il_0002: ldftn void delegatedemo. Program: showname (string) // push the function pointer of showname (non-managed pointer native int type) to the computing stack.
Il_0008: newobj instance void delegatedemo. hellocallback:. ctor (object, native INT) // create a new object and push the object reference to the computing stack.
Il_000d: stloc.0 // The current value pops up at the top of the computing stack and stores it in helloshow, a local variable at index 0.
Il_000e: Ret // return from the current method, and push the returned value (if any) from the caller's computing stack to the called's computing stack.
} // End of method program: Main

From the intermediate code, we can see that the hellocallback class constructor has two parameters: hellocallback:. ctor (object, native INT), and my code is

Hellocallback helloshow = new hellocallback (showname); there is only one parameter, which should not be compiled. The compiler has done something for us in this place,

When it knows that the delegate is to be constructed, it will analyzeSource codeTo determine the object to be referenced, that method. The object reference is passed to the object, and the showname function pointer is passed to the native Int.

3. Call the callback Method

The source code is as follows:

Internal delegate void hellocallback (string name); Class program {static void main (string [] ARGs) {hellocallback helloshow = new hellocallback (showname); helloshow ("hello ");} static void showname (string name) {console. writeline (name); console. readline ();}}

The intermediate code is as follows:

. Method private hidebysig static void main (string [] ARGs) cel managed
{
. Entrypoint
// Code size 27 (0x1b)
. Maxstack 3
. Locals Init ([0] class delegatedemo. hellocallback helloshow)
Il_0000: NOP
Il_0001: ldnull
Il_0002: ldftn void delegatedemo. Program: showname (string)
Il_0008: newobj instance void delegatedemo. hellocallback:. ctor (object,
Native INT)
Il_000d: stloc.0
Il_000e: ldloc.0 // load the local variable at index 0 to the computing stack.
Il_000f: ldstr "hello" // loads a String constant into the stack.
Il_0014: callvirt instance void delegatedemo. hellocallback: invoke (string) // call the post-binding method on the object and push the return value to the computing stack.

Il_0019: NOP
Il_001a: Ret
} // End of method program: mains

 

Helloshow ("hello") is equivalent to helloshow. Invoke ("hello ");

The complete code is as follows:

Internal delegate void hellocallback (string name); Class program {static void main (string [] ARGs) {hellocallback helloshow = new hellocallback (showname); helloshow. Invoke ("hello ");
Console. Readline ();
 
} Static void showname (string name) {console. writeline (name );}}

How is invoke implemented? Check the intermediate code as follows:

 
. Method public hidebysig newslot virtual instance void invoke (string name) runtime managed {}// end of method hellocallback: invoke

Runtime managed indicates that this method has CLR processing at runtime, which is similar

Delegate [] delegates = helloshow. getinvocationlist ();
For (INT I = 0; I <delegates. length; I ++)
{
Delegate callback = delegates [I];
Methodinfo method = callback. method;
Method. Invoke (helloshow. Target, new object [] {"hello "});
}

4. Delegated chain

A delegate chain is a collection of delegate objects. With it, you can call all delegate methods.

Delegate has two common attributes.

TargetObtain the class instance. The current delegate will call the instance method for it. (Static method access is empty)

MethodObtain the methods represented by the delegate.

The use of multicast delegation is as follows:

 
Namespace delegatedemo {internal delegate void hellocallback (string name); Class program {static void main (string [] ARGs) {hellocallback helloshow = new hellocallback (showname); helloshow + = showchname; helloshow. invoke ("hello"); console. readline ();} public static void showchname (string name) {console. writeline ("Hello:" + name);} public static void showname (string name) {console. writeline (name );}}}

View the multicastdelegate source code. We can see that the delegate chain is saved in the private object _ invocationlist;

 
Hellocallback helloshow = new hellocallback (showname );

_ Invocationlist is initialized to object []. The first element of the array is the new hellocallback (showname) delegate.

 
Helloshow + = showchname;

+ The operator overload is used. The actual call is the combine of delegate, and the-number actually calls the remove of delegate.

 
 



 

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.