[C # advanced series] 16 delegation,

Source: Internet
Author: User

[C # advanced series] 16 delegation,

The principal purpose of delegation is to implement the callback function mechanism, which can be understood as a function pointer (the only difference lies in the concept of delegation chain ).

However, the internal mechanisms of delegation are complicated.

A commissioned story

delegate void razor(String userName);

A simple delegate is defined.

In fact, after compilation, this code is very similar to the following code:

Class Razor: System. multicastDelegate {// constructor public Razor (Object @ object, IntPtr method); public virtual void Invoke (Int32 value ); // Implement Asynchronous callback to the callback method public virtual IAsyncResult BeginInvoke (Int32 value, AsyncCallback callback, Object @ object); public virtual void EndInvoke (IAsyncResult result );}

That is to say, the delegate is actually a class derived from MulticastDelegate. There are four methods.

Because it inherits the MulticastDelegate class, it also inherits the fields, methods, and attributes of the MulticastDelegate class.

The three most important fields are the operation object _ target (if the static method is NULL) pointing to the instance method passed in by the delegate ), the _ methodPtr used by CLR to identify the callback method (this is not a pointer, but an internal parameter value to indicate a method ), when constructing the Delegate chain, the Delegate array references _ invokationList (in the Delegate through Delegate. combine or + = is bound to multiple callback functions. Otherwise, the value is null ).

However, when using the delegate:

First, check whether the _ invokationList of the delegate is null. If it is null, it means that no delegate chain is established. In fact, the delegate Razor (actually a class instance) is used to call the Invoke method, at this time, a parameter value is passed to the Invoke method, which is the internal parameter value stored in _ methodPtr, used to identify the parameter value of the passed instance method.

If _ invokationList is not null, it indicates that a delegate chain has been established, so the Invoke method of each delegate in the delegate array will be called separately for a long time, the execution method is naturally the method specified by _ methodPtr in each delegate.

As for removing the Delegate (use Delegate. Remove or-= ).

The execution of functions in the delegate chain starts to be executed according to the binding order. However, if a result is returned, the return result of the last bound function must be returned.

However, there are some problems with this method of executing the delegate chain. For example, a delegate in a delegate chain throws an exception or the subsequent delegate functions cannot be executed because the blocking time for calling the database query is too long.

Therefore, the MulticastDelegate class provides an instance method GetInvokationList (), which returns the Delegate array pointed to by _ invokationList.

Generic Delegation

Generic delegation is used to solve the problem of too many similar delegates, and the generic delegation provided by. NET is also very simple. The 17-parameter-specific Action delegation and 17-parameter-specific Func delegation.

The return value of the Action delegate is void, and the return value type of the Func delegate is the TResult of the specified type.

However, if you need to use the ref and out keywords to PASS Parameters by reference, you have to define your own delegate. This is because the in and out identifiers are used for the coordination and inverter of generic delegation. (Refer to the generic chapter here)

C # syntax sugar about Delegation

A normal Commission is as follows:

Static void Main (string [] args) {Razor razor = null; razor + = new Razor (Blower); razor ("Troy123"); Console. read ();} static void Blower (String userName) {Console. writeLine (userName + ": Actually this is a hair dryer ");}

However

razor += new Razor(Blower);

This syntax looks strange (strange at the beginning, but actually it's okay), So C # provides some simplified Syntax:

  • No need to construct delegate object
    • Some functions can directly pass in the callback method as follows, instead of calling new Razor to construct the delegate object as before. On the surface, it is actually only done internally, but will still construct the delegate object and then call it.

      Void callback function (object obj) {Console. WriteLine (obj);} ThreadPool. QueueUserWorkItem (callback method, 5 );
  • Callback method (lambda expression) does not need to be defined)
    • The previous code can be written as follows:
      ThreadPool.QueueUserWorkItem(l=>Console.WriteLine(o),5);
    • Lambda expressions look weird, but they are used to being very useful. This is done by creatingAnonymous FunctionsReplace the callback function. (This method is good, but if a callback function is called in multiple places, it is better to use the previous method)
    • Anonymous functions are usually marked as static and private. The former is more efficient because no additional this parameter is required, and the latter is for security. (Unless an anonymous function uses an instance Member)
      • The following are examples:
        Delegate void Bar (out Int32 z); Func <string> f = () => "Troy"; Func <Int32, string> f1 = (Int32 l) => l. toString (); Func <Int32, string> f2 = (l) => l. toString (); // inferred type: Func <Int32, Int32, string> f3 = (l, m) => {Console. writeLine (m); return l. toString () ;}; // Add brackets for multiple statements Bar B = (out Int32 n) => n = 5; // For the reference type, the specified
  • Local variables can be passed to the callback method without being manually wrapped into the class.
    • It looks like it is actually quite simple. That is, lambda expressions can directly use local variables and parameters without passing parameters.

Delegation and reflection

System. Delegate. MethodInfo provides a CreateDelegate method, which dynamically creates a Delegate.

Then you can use the Delegate. DynamicInvoke method to call it dynamically.

I didn't think too many things would be used in this specific case. After all, I have little experience in the world.

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.