The delegate function in. Net is similar to the method pointer in c or c ++. It can call the delegate to complete a function like calling a method, or return a certain type of result. However. net is a more advanced language, and the Delegate is also more advanced. The Delegate is a data interface that contains the pointer to the call target and the call method. all the delegates defined in. Net are inherited from MulticastDelegate, that is, multicast delegates. The so-called multicast delegates can contain multiple call methods.
I. Let's first look at the definition of delegation:
The following C # Code definition delegate
Public delegate void DoSomething (int times );
The delegate definition consists of five parts.
1) public indicates the accessibility of the Delegate
2) The delegate keyword indicates that a delegate is to be defined.
3) void indicates the return value of the delegate definition method
4) DoSomething is the delegate name.
5) (int times) is the parameter list of the delegate method. The parameter list here can include the ref parameter, the out parameter, or the Variable Number Parameter of parms; note that if multiple methods are called in the delegate, only the calculated value of one delegate method that is successfully executed can be returned when the out parameter is used.
Defining a delegate in C # is very simple. You only need to add one delegate keyword before the return value of the method definition.
However, we know that all user-defined delegation are inherited from MulticastDelegate, while MulticastDelegate is a class, so the custom delegate is certainly a class; the above code's IL code proves our inference:
Copy codeThe Code is as follows:. class public auto ansi sealed delegates. DoSomething
Extends [mscorlib] System. MulticastDelegate
{
// Methods
. Method public hidebysig specialname rtspecialname
Instance void. ctor (
Object 'object ',
Native int 'method'
) Runtime managed
{
} // End of method DoSomething:. ctor
. Method public hidebysig newslot virtual
Instance void Invoke (
Int32 times
) Runtime managed
{
} // End of method DoSomething: Invoke
. Method public hidebysig newslot virtual
Instance class [mscorlib] System. IAsyncResult BeginInvoke (
Int32 times,
Class [mscorlib] System. AsyncCallback callback,
Object 'object'
) Runtime managed
{
} // End of method DoSomething: BeginInvoke
. Method public hidebysig newslot virtual
Instance void EndInvoke (
Class [mscorlib] System. IAsyncResult result
) Runtime managed
{
} // End of method DoSomething: EndInvoke
} // End of class delegates. DoSomething
Ii. Define the delegate. Of course, to use it, let's look at how to use the delegate:
In. Net, there are three types of delegation: method, anonymous method, and lambda expression. We use the method definition to see how to use the delegate.Copy codeThe Code is as follows: using System;
Namespace delegates
{
Public delegate void DoSomething (int times );
Class Program
{
Static void Main (string [] args)
{
// Declare the delegate variable and assign a value to the delegate variable
DoSomething @ do = DoA;
// You can use the "+" or "+ =" to add a method to the delegate.
@ Do + = DoB;
// The methods in the delegate will be executed successively according to the order in which the delegate is added.
@ Do (1 );
// You can also use the-or-= to remove a method from the delegate.
@ Do-= DoA;
@ Do (2 );
@ Do-= DoB;
// After all the methods in the delegate are removed, the delegate can still be called, but nothing is done.
@ Do (3 );
Console. Read ();
}
// Define a method to delegate the same parameters and return values
Static void DoA (int times)
{
Console. WriteLine ("Do A {0}", times );
}
// Define a method to delegate the same parameters and return values
Static void DoB (int times)
{
Console. WriteLine ("Do B {0}", times );
}
}
}
In the Main method in the above Code, we first define the variable @ do that delegates DoSomething, and assign the DoA method to this variable directly; then we added another method to the delegate using the + = symbol or the + sign. Of course, we can also use-or-= to remove the method from the delegate.
A delegate is more powerful than a C/C ++ method pointer because it can accommodate multiple methods or execute a ++-operation to add or delete methods from the method list.
Note the following when executing the delegate addition and subtraction operation:
1. Statement of delegation statement
The following code can be used to delegate a statement:Copy codeThe Code is as follows: DoSomething @ do = DoA;
This is actually a short way of writing, we know in. net 1. writing in x is not allowed only. in. Net 2.0. net 1. x must be writtenCopy codeThe Code is as follows: DoSomething @ do = new DoSomething (DoA );
We need to add DoB to @ do in the Declaration.Copy codeThe Code is as follows: DoSomething @ do = DoA + DoB;
The compiler does not need to write this statement. It must be written in. Net 1.x.Copy codeThe Code is as follows: DoSomething @ do = new DoSomething (DoA) + new DoSomething (DoB );
2. What will happen when I subtract the nonexistent method from the delegate?
See the following code:Copy codeThe Code is as follows: DoSomething @ do = DoA;
@ Do-= DoB;
In the first line of code, I have lived @ do and granted the DoA to it. In the second line of code, I tried to subtract DoB from @ do. DoB does not exist in the @ do method list, what will happen? First, the compiler does not report an error. The program can be compiled normally. The Code Execution finds that the program can be executed normally. the DoA method is correctly executed when @ do is called. net embraces the mistakes made by our programmers. When we subtract a method not included in the delegate from the delegate variable, no errors will be reported and executed normally.
3. What will happen if all the delegates are subtracted from the Commission? See the following code:
Copy codeThe Code is as follows: DoSomething @ do = new DoSomething (DoA) + new DoSomething (DoB );
@ Do-= DoA;
@ Do-= DoB;
@ Do (1 );
This code can be compiled successfully, but NullReferenceException will be reported during runtime; this is obviously not what we want, so pay special attention to the delegate subtraction.Copy codeThe Code is as follows: <span style = "text-decoration: line-through;"> public delegate void DoIt (string task );
Class Test
{
Static void Main (string [] args)
{
// DoIt declaration. It is valid to assign a broader method to a parameter.
DoIt doIt = new DoIt (DoItImpl );
DoIt ("hello ");
}
// The string type can be implicitly converted to the object type, which is wider than the parameter in the delegate definition.
Static void DoItImpl (object task)
{
Console. WriteLine ("DoItImpl {0}", task );
}
}
</Span>