The secret behind Delegate

Source: Internet
Author: User

The secret behind Delegate

On the surface, using delegate is quite simple.

Use the delegate keyword to define an instance, use the old new Method to create an instance, and use the familiar method call method to call the instance, but not the method name, but the delegate name. But behind this, the CLR has done a lot for us. When we write down the following sentence, public delegate void FeedBack (Int32 val) is actually equivalent to the following code (excluding some multithreading-related code) pubic class FeedBack: multicastDelegate {public FeedBack (Object object, IntPtr methodPtr) {xxxx
} Public virtual void Invoke (int32 val);} First, delegate is a class. This class will automatically inherit MuticastDelegate. Then, the constructor of this class is shown above. Let's first look at the second parameter methodPtr, which can be understood as a function pointer or function address. When the delegate is actually running, find the address of the function and run the function. Yes, we need to first find the address of this function. For static functions, the address is fixed, and for instance functions, the internal function address is not fixed, it needs to determine a specific instance first. This is not only the purpose of the first parameter, but also the reference of a specific instance. For a static function, a null is input by default. In fact, in the base class MutiCastDelegate, there are three important non-public attributes: _ target _ methodPtr_invokationlist. Two or two attributes correspond to the two parameters passed in by the constructor. The third attribute is related to the delegate chain, the default value is null. We will not discuss it first. That is to say: Delegate is actually just a wrapper, packaging the objects that require real operation and their methods.That is to say, the constructor of the delegate completes the correspondence with the actual object and actual method, while the call is another method called Invoke (int32 val ). This method triggers the call of a real method. About delegate chain... I will not go into it because it is really lazy .. It can be understood that a delegate array stores these delegates at a time, and then calls them one by one through foreach... This results in the "chain reaction" that the methods in the entire delegate chain are called ". Because the internal implementation is an array, the specific call order is determined, rather than random. These methods are called in sequence based on the order in which they are added to the delegate chain. In earlier versions, two methods are used to concatenate a chain through the Delegate. Combine static method ). Like a chain in real life, there are two parameters. The first parameter is a part of the chain that has been installed, and the second parameter is to be installed. (The chain is implemented by array.) The second method is C #. To better assist the delegate operation, it automatically reloads the + = and-= operators. That is to say, the delegate instance can be simply spliced by + = and-=. This undoubtedly greatly simplifies the delegation chain. (As for how to overload it, It is lazy .. .) After completing the delegated link, you only need to directly call the same delegate to call the delegated link. The internal algorithms of the delegate call each spliced element in sequence. However, one drawback is that if a delegate has a returned value, only the return value of the last delegate can be returned. All the previous delegate return values will be discarded. What are the solutions.
As mentioned above, if you directly invoke the delegated chain, only the returned values at the end of the chain are output, and simple and direct chained calls pose a huge risk, if a delegate throws an exception, the entire chain gets stuck. If you want the return value of each delegate, you cannot use the above method. For Delegation and generics, we first define a delegate public void FeedBack (Int32 value); then we suddenly need another delegate .. Can o (distinct □distinct) o public void FeedBack (string value) be defined in this way? Absolutely not !! The essence of delegation is class, so the above practice just repeats the definition of a class with the same name. The delegation can be more powerful by integrating with generics. See the complete example below.
Public delegate void FeedBack <T> (T para); public delegate void FeedBack <Tint, Tstr> (Tint para1, Tstr para2 ); can class delegation have generics? {public static void Main (string [] args) {FeedBack <Int32> fb = new FeedBack <int> (FeedBackInt ); feedBack <String> fb2 = new FeedBack <string> (FeedbackString); FeedBack <int, string> fb3 = new FeedBack <int, string> (FeedbackIntString); fb. invoke (2); fb2.Invoke ("haha"); fb3.Invoke (60, "haha"); Console. readKey ();} public static void FeedBackInt (Int32 val) {Console. writeLine (val);} public static void FeedbackString (String str) {Console. writeLine (str);} public static void FeedbackIntString (int val, string str) {Console. writeLine (val + ":" + str );}}}

 

I don't know if you have an idea in your mind .... That is what Microsoft has come up with: with generics, You can include almost all the possible delegation you will use for programming !!!! They did .. This is the self-built delegation owned by FCL. Func. has the following delegate, and the maximum number of parameters is 16. If there are more, this method is very problematic. Microsoft also recommends that you use the built-in delegation when you need to use the delegate, instead of creating the delegate type on your own. So let's follow this convention. Of course, these generic types may not meet your requirements. For example, you need this delegate void bar (ref int32 z); or your generic delegation requires some constraints. You have to define the delegate .. The most common use of delegate should be the event processing mechanism in webform. We often see the following statement: button1.Click + = button#click; void button#click (Object sender, EventArgs e ){
// Do something, the button was clicked...
} Few people were surprised by this writing method when they were learning it .. This is the syntactic sugar provided by C. The normal method is button1.Click + = new EventHandler (button#click). Do you know me now? It is simply splicing the delegate chain. The above syntactic sugar is the first syntactic sugar in the delegate. You can directly provide the function name to be included in the delegate without entrusting the instance. (Events is a safer delegate. actually, the self-built EventHandler delegate is used. Then, each time different controls are triggered, the EventHandler (sender, e) delegate is used to trigger the actual method. The OK delegate is sent here first.

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.