delegate, which occupies a very important place in C # programming, a delegate can encapsulate a function into a delegate object, and multiple delegates can be merged into a delegate, which can be stored, passed, and invoked as normal objects, so that the implementation of the function callback mechanism in C # is essentially dependent on the delegate. The delegate keyword for C # is used to declare a delegate with the ability to map a declaring delegate type to a System.Delegate class, which is located in Mscorlib.dll and is one of the base core classes of. Net. Declaring a delegate with the delegate keyword essentially creates a system.delegate derived class, so the delegate type is not a struct or other type, it is a class. A delegate object is an instance of a class. The following is a declaration of the delegate class:
Copy Code code as follows:
Public abstract class Delegate
Delegate is the base class for the delegate type, and the multicast delegate in C # is actually the MulticastDelegate class, which is a derived class of System.Delegate, and the action described in this article, Func generic delegates are actually derived types of multicastdelegate classes. In C # When we use the delegate keyword to declare a delegate type, it is actually the C # compiler, based on the method signature we declare, to help us generate a class that is derived from MulticastDelegate that matches the signature. Before a large number of generics are applied, we may use the delegate keyword to declare many delegate types when we write a C # program, because these types correspond to different method signatures. Viewing mscorlib from the Object Browser of Visual Studio can see these two important generic delegates:
In addition to the action, other delegates are generic, in fact, some generic classes. This is. NET core library, all generics are delegated. These generic delegates are divided into Func, action, and they can replace almost all delegate types in C # by virtue of their generic attributes, which means that in general, you can wrap all the functions without declaring any new delegate types in our program. For example, we have two methods:
Copy Code code as follows:
public static void Otputstring (String str)
{
Console.WriteLine (str);
}
public static int Add (int a, int b)
{
return a + B;
}
The Func generic delegate has an extra TResult type parameter than the action, for cases where the function has a return value, and the action generic delegate is used for a function that has no return value. This can be done when we want to get the delegate object for both methods:
Copy Code code as follows:
var action = new action<string> (otputstring);
Action ("OutputString invoked!");
var func = new Func<int, int, int> (ADD);
var sum = func (3, 5);
Console.WriteLine (sum);
As you can see, when we wrap a function with a return value into a delegate object, use the Func delegate, and if the function has no return value, use the action, the kernel library provides the shortest generic delegate type parameter of 0, and the longest is 8. Therefore, the action and its generic delegate can match any function that has no return value, and the number of arguments is 0 to 8. Similarly, a Func generic delegate can match any function that has a return value and a number of arguments from 0 to 8. In general, there are no more than 8 parameters for a function in a program, even if there are more than 8, we can declare a new generic delegate type to respond to
Copy Code code as follows:
delegate void Action<t1, T2, T3, T4, T5, T6, T7, T8, t9> (T1 p1, T2 p2, T3 P3, T4 P4, T5 P5, T6 P6, T7 P7, T8 P8, T9 P9);
There is no performance penalty for using these generic delegates, which keeps the usage style of the delegates in the program consistent. The only drawback is that the name of the type cannot express the specific purpose, for example EventHandler delegate, we know it as a delegate for event processing as soon as we see the name. Using the Action<object,eventargs> delegate, we cannot see the purpose of this type of delegate from the name.
Generic delegates have the ability to override all other delegates, whether a generic delegate or an ordinary delegate, when to use it, and in which case, each may have a different profile, but in the final analysis, the generic delegate can unify the code style of the program and the advantages of easy to use everywhere is very significant.