The past few days have been relatively idle, just some time ago I bought this CLR Via C #. Everyone in the. Net industry knows that master Jeffrey has never read this classic book.
However, in C #, there are many classics. At that time, I was introduced to C # Through the book C # And. NET 3.0 advanced programming design, also known as C # bible.
The delegate in CLR Via C # is very good, in-depth, refreshing, and memorable. Remember to include ILDasm and
With Reflector, we can take a deeper look at some questions. There are many ways to read, ask, and refine, because everything follows
"100 principle": Among the characters, there are only 20 nutritious texts in the same area. Once we grasp them, we will understand them. Well, we will be confused here.
Q: What is delegation?
A: The delegate is A class inherited from MulticastDelegate. If you do not believe it, you can use ILdasm to check it.
1 public delegate void FlyAction();
Q: I saw the Invoke method from ILdasm, but I didn't see the definition of this method in Delegate? Why?
A: This actually obfuscated the delegate keyword and the Delegate type in FCL. For the delegate keyword, the compiler and CLR have made A lot of optimizations for us,
It also masks a lot of complicated details, but the Delegate in FCL does not.
Q: I know that the method can be passed as a parameter to the delegate, and then the delegate invoke can be used anywhere to execute the method as a parameter. How can I do this?
A: Since the method of this parameter can be referenced anywhere, we need to see how the method intrude into the delegate.
① First look at the instance code:
1 namespace Demo 2 { 3 class Program 4 { 5 public delegate void FlyAction(); 6 7 static void Main(string[] args) 8 { 9 Bird bird = new Bird();10 11 FlyAction action = new FlyAction(bird.Fly);12 13 action.Invoke();14 }15 }16 17 public class Bird18 {19 public static Random rand = new Random();20 21 public void Fly()22 {23 return "i can fly " + rand.Next();24 }25 }26 }
From the first QA, we can also see that the delegate is actually a class. When I use a new class, bird. fly is actually a parameter of the class constructor.
② Let's take a look at the constructor in the generated IL.
At this time, the problem arises. Why is there two parameters here, while the new FlyAction (bird. Fly) is a parameter, which seems to be problematic and does not comply with the language regulations?
In fact, the compiler provides an intermediate layer through which a conversion is made to hide the specific logic. In fact, the delegate provides
A Target and Method attribute. When we pass in the bird. Fly, the Target records the Bird class, and the Method records the Fly Method in the Bird, so the invoke
The Fly method in the Bird class is automatically triggered. The evidence is as follows:
Here, we add that if the new FlyAction Method is a static Method, the compiler can find the trigger Method by using the Method if the Target is null.
Q: Why is it not recommended that the callback method return values in multicast delegation? Even if there is a return value, the method in multicast can only return the last value. If I want to obtain each method
What should I do? The instance code is as follows:
1 class Program 2 { 3 public delegate string FlyAction(); 4 5 static void Main(string[] args) 6 { 7 Bird bird = new Bird(); 8 9 FlyAction action1 = new FlyAction(bird.Fly);10 11 FlyAction action2 = new FlyAction(bird.Fly);12 13 FlyAction action3 = new FlyAction(bird.Fly);14 15 action1 += action2;16 17 action1 += action3;18 19 Console.WriteLine(action1.Invoke());20 21 var result = action1.GetInvocationList();22 23 Console.Read();24 }25 }26 27 public class Bird28 {29 public static Random rand = new Random();30 31 public string Fly()32 {33 return "i can fly " + rand.Next();34 }35 }
A: Since "Multicast" is mentioned, it is actually the publisher. In the internal source code, A List is maintained and all the methods in "Multicast" are put into the List, when Invoke,
Call the methods in the following order by repeating the List. This is why we recommend that you do not use the "Return Value" method.
Next we can use GetInvocationList to obtain the methods in this list.
Then let's take a look at how the code in the GetInvocationList is written.
If you see this. _ invocationList and for loop, is there a completely clear feeling? If you want to get the return value of each method, you can only use
After GetInvocationList is obtained, it is manually processed. Only in this way can the return values of each method in "Multicast delegate" be obtained.
Q: Could you go to bed after the last question? Can you dynamically create a delegate?
A: Yes. The CreateDelegate method is provided in Delegate, which can be dynamically created. For example, you will know.
1 class Program 2 {3 public delegate string FlyAction (); 4 5 static void Main (string [] args) 6 {7 Bird bird = new Bird (); 8 9 // find the method 10 var method = typeof (Bird) under the class ). getMethod ("Fly", BindingFlags. instance | BindingFlags. public); 11 12 var mydelegate = (FlyAction) Delegate. createDelegate (typeof (FlyAction), bird, method); 13 14 var result = mydelegate. invoke (); 15} 16} 17 18 public class Bird19 {20 public string Fly () 21 {22 return "I can fly" + new Random (). next (); 23} 24}