The principal is to implement the callback function mechanism, which can be understood as a function pointer (the only difference is that the concept of a delegate chain is more).
However, the use of this can be understood, but the internal mechanism of the Commission is more complex.
A delegate's story
Delegate void Razor (String userName);
A simple delegate is defined.
In fact, after compiling this code is very similar to the following code:
classRazor:System.MulticastDelegate {//constructor Function PublicRazor (Object @object, IntPtr method); Public Virtual voidInvoke (Int32 value); //implementing an asynchronous callback to a callback method Public VirtualIAsyncResult BeginInvoke (Int32 value, AsyncCallback callback, Object @object); Public Virtual voidEndInvoke (IAsyncResult result); }
This means that the delegate is actually a class derived from MulticastDelegate, which has four methods.
Because of inheriting the MulticastDelegate class, the fields, methods, and properties of the MulticastDelegate class are also inherited.
There are three fields that are most important, that is, the operand of the instance method that points to the delegate's _target (if the static method is null), the CLR is used to identify the _methodptr of the callback method (this is not a pointer, but an intrinsic parameter value that represents a method), The reference _invokationlist of the delegate array when constructing the delegate chain (the value is only after the delegate has multiple callback functions through delegate.combine or + =, otherwise null).
When you use a delegate, you will:
First to see if the _invokationlist of this delegate is null, it means that the delegate chain is not established, then the delegate razor (actually an instance of a class) is used to invoke the Invoke method, which is passed to the The Invoke method is a parameter value, which is the internal parameter value stored by the _methodptr , which identifies the parameter value of the passed-in instance method.
If _invokationlist is not NULL to indicate that a delegate chain has been established, then the invocation method of each delegate in the delegate array is called for a long time, and the method of execution is naturally _methodptr the specified method within each delegate.
And as for the removal of the delegate (with delegate.remove or-=).
The functions in the execution delegate chain are executed in the order in which they are bound, but if there is a return, it must be the return result of the last bound function.
However, there are some problems with this way of executing a delegate chain, such as a delegate in a chain that throws an exception or because the blocking time of a call to a database query is too long to cause subsequent delegate functions to execute.
So the MulticastDelegate class provides an instance method of Getinvokationlist (), which returns the delegate array _invokationlist points to.
Generic delegate
Generic delegates are intended to solve the problem of too many similar delegates, and. NET provides a generic delegate that is also very simple, with 17 parameters different from the action delegate and 17 parameters different from the Func delegate.
Where the action delegate is a return value of void, and the return value type of the Func delegate is the TResult of the type that you specify.
However, if you need to pass parameters in a reference way using the ref and out keywords, then you have to define your own delegate. Because the in and out identifiers are used when the covariance and contravariance of generic delegates, they cannot be used in order to get confused. (Refer to the generic chapter here)
C # syntax sugar for delegates
A normal delegate is the following
Static voidMain (string[] args) {Razor Razor=NULL; Razor+=NewRazor (blower); Razor ("Troy123"); Console.read (); } Static voidBlower (String userName) {Console.WriteLine (UserName+": Actually this is a hair dryer"); }
However
New Razor (blower);
This syntax looks strange (at first strange, it's okay), so C # provides a few simplified syntax:
- No need to construct delegate object
-
Some functions can pass directly to the callback method as follows, rather than needing new razor to invoke the constructor object as before. On the surface, it is actually handled internally, or the delegate object is constructed and then called.
void callback function (object obj) { Console.WriteLine (obj); } 5);
- You do not need to define a callback method (lambda expression)
- Local variables can be passed to the callback method without manual wrapping to the class
- It looks very round, actually very simple. Is that lambda expressions can use local variables and parameters directly, without requiring you to pass arguments.
Delegate and reflection
System.Delegate.MethodInfo provides a createdelegate method, as the name implies, to dynamically create a delegate.
You can then use the Delegate.dynamicinvoke method to invoke it dynamically.
About this specific also did not think too many places will use, after all, see the less.
"C # Advanced series" 16 delegates