Home > Article > Backend Development > Detailed introduction to delegation and anonymous delegation in C#
This article mainly introduces the relevant information of C# delegation and anonymous delegation in detail. It has certain reference value. Interested friends can refer to it.
Originally I wanted to write an article "Delegation" "The Past and Present Life of Lambda Expressions", but only the delegation part has been written a lot, so I will separate the content about Lambda expressions and write later.
I don’t know who invented Lambda expressions. I just remember that the first time I came into contact with Lambda expressions was when using VS2008, so let’s first think that it was invented by Microsoft.
Lambda expressions have become more and more popular since I came into contact with them. They are now supported in Java 8, and kotlin has extensively copied C# and F# (didn’t C# treat Java like this once upon a time)? . In fact, this fully illustrates the importance of Lambda expressions. To understand Lambda, you first need to understand delegation.
Delegation:
Suppose now we want to develop a program that processes two integers (assuming that the addition operation is processed first)
public class Worker { /// <summary> /// 处理两个数 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public int HandleTwoNumber(int a,int b) { return a + b; } } static void Main(string[] args) { int a = int.Parse(Console.ReadLine()); int b = int.Parse(Console.ReadLine()); Worker worker = new Worker(); int result = worker.HandleTwoNumber(a, b); Console.WriteLine(String.Format("Result:{0}", result)); string p = Console.ReadLine(); }
If after a period of time, we need to change it to a subtraction operation:
public class Worker { public int HandleTwoNumber(int a,int b) { return a - b; } }
Although the change from a+b to a-b is very small, subsequent There may be multiple changes here (from reduction to division...). If there is a change, the change should be encapsulated. Here we can abstract the operational behavior of a and b. What abstraction should we use? Delegate
public class Worker { public delegate int TwoNumberHandleMethodDelegate(int x, int y); public int HandleTwoNumber(int a,int b) { return a + b; } }
public delegate int TwoNumberHandleMethodDelegate(int x, int y); Annotated with delegate here, it indicates that this is a delegate definition. If you remove the delegate and look at the definition, you will find that this is an abstract method without a method body. So the meaning of delegation is: the type of method with the same signature form as the abstract method. A delegate is a new data type you define. It is the same data type as int and class. int represents an integer, and any integer can be assigned to an int-type variable; TwoNumberHandleMethodDelegate represents a method that receives two int-type parameters and returns an int-type result. Therefore, methods that meet the above requirements can be assigned to variables of the TwoNumberHandleMethodDelegate type.
In this way, the Worker code can be modified as:
public class Worker { public delegate int TwoNumberHandleMethodDelegate(int x, int y); public int HandleTwoNumber(int a, int b, TwoNumberHandleMethodDelegate handle) { return handle(a, b); } }
In this way, the operations of a and b are encapsulated, and all changes are handed over to The caller handles it. The meaning here: HandleTwoNumber processes two integers a and b. The specific processing is implemented by handle. At this point you may ask, how to call this method? The call is as follows:
private static int Add(int a, int b) { return a + b; } private static int Sub(int a, int b) { return a - b; } static void Main(string[] args) { int a = int.Parse(Console.ReadLine()); int b = int.Parse(Console.ReadLine()); Worker.TwoNumberHandleMethodDelegate method = new Worker.TwoNumberHandleMethodDelegate(Add); Worker worker = new Worker(); int result = worker.HandleTwoNumber(10, 10,method); //int result = worker.HandleTwoNumber(10, 10, Sub);//简化版 Console.WriteLine(String.Format("Result:{0}", result)); }
According to the above program, the Main code block is the caller of the worker. As the caller, you should know best what you want the worker to do. . Therefore, as the callee's worker, it only needs to receive the a\b parameters given by the caller Main and execute the algorithm method customized by Main, and then execute the algorithm according to the algorithm and return the result. Although the above code is simple, its meaning is far-reaching. As your programming time increases, I believe your understanding will become deeper.
In addition to the standard way of assigning values to delegate variables, they can also be simplified:
Worker.TwoNumberHandleMethodDelegate method = new Worker.TwoNumberHandleMethodDelegate(Add); Worker worker = new Worker(); int result = worker.HandleTwoNumber(10, 10,method); //可简化为 // int result = worker.HandleTwoNumber(10, 10,Add);
The compiler will automatically check whether Add conforms to the definition of TwoNumberHandleMethodDelegate. If it complies, it is allowed to directly assign the method name to the delegate variable.
Anonymous Delegate
Through the above sample code, we can easily find that the TwoNumberHandleMethodDelegate method variable is assigned the value Add(Sub), so when calling method(...) is equivalent to calling Add(.....). In this way, we can think that
method is completely equivalent to Add. Since they are equivalent, can we directly assign the definition content of Add to the method variable? The answer is yes:
static void Main(string[] args) { Worker.TwoNumberHandleMethodDelegate method =private static int Add(int a, int b) { return a + b; }; }
But it’s not possible to apply it mechanically like the above. You still need to make modifications. The modification content is: because the current code is in the Main method, the access modifier is removed, and static should also be removed; at the same time, the compiler knows that you want to assign a value to the method, so the value to be assigned must meet the return type of int, so all Int is unnecessary to remove at this time; because after assignment, method is equivalent to Add, and subsequent calls can be completed through the method variable, and all Add method names do not need to be removed. The code changes to the following form:
static void Main(string[] args) { Worker.TwoNumberHandleMethodDelegate method = (int a, int b) { return a + b; }; }
After the above modification, the content has been simplified a lot, but what is the right end of the = assigned by method? At this time, the compiler cannot correctly identify that this is a method, because the definition of the method needs to include: access modifier, return type, method name, parameter list, and method body. Although you know in your heart that this is a simplified method, the compiler does not understand your mind..., that doesn't matter as long as we tell the compiler that what follows is a simplified method.
static void Main(string[] args) { Worker.TwoNumberHandleMethodDelegate method = delegate(int a, int b) { return a + b; }; }
As you would expect, now the compiler knows = The right side is your simplified method; ok, now it can be assigned and used normally.
Through the above definition, we find that the simplified method marked with delegate does not have a fixed name like Add/Sub. Therefore we call this method anonymous delegation (I am used to calling it anonymous method).
You may also notice that after the anonymous delegate is defined, it is assigned to the local variable method in the Main code block. Therefore, when the scope of the method is exceeded, the method will never have a chance to be called. This leads to the most common uses of anonymous methods, anonymous delegates, and anonymous functions, which are to define functional code that only needs to be used once.
The above is the detailed content of Detailed introduction to delegation and anonymous delegation in C#. For more information, please follow other related articles on the PHP Chinese website!