During the development process, static methods are called by adding a vertex after the type name and then the name of the called method. The method called for a type instance is called by a new object, add the method name, which is the most familiar method. You can also call it by reading CLR metadata and using reflection. When calling methods using reflection, the two most important classes are System. type and System. reflection. methodInfo. to call a method using the MethodInfo-type Invoke method, you must pass in the reference of the target object instance. As follows:
PublicclassCalculate {// Using Reflection, you can call the private method private intAdd (intleftNum, intrightNum)
{ReturnleftNum + rightNum;} classProgram {staticvoidMain (string [] args)
{// Use type. the getmethod method gets the type method. BindingFlags sets the scope of the search method. // in this example, it is a public method and the private method is not static, if you want to find the static method // you need to set BindingFlags. static MethodInfomethod = typeof (Calculate ). GetMethod ("Add", BindingFlags. public | BindingFlags. nonPublic | BindingFlags. instance); if (method = null) return // call the method parameter object [] paras = {10, 20}; // target object Instance: new Calculate ()
Objectresult = method. Invoke (newCalculate (), paras); Console. WriteLine (result); Console. ReadLine ();} delegate method
Any object can call a delegate, as long as the method return value and method signature are the same as the delegate declaration.
By reading the CLR source code, we sorted out the important fields of the delegate class and several common methods. The custom Delegate types are derived from MulticastDelegate.
PublicabstractclassDelegate: ICloneable, ISerializable {// call the target object. The instance method is a type instance reference, and the static method is null internalObject_target; // point to the call method internalIntPtr_methodPtr; // Delegate constructor protectedDelegate (Objecttarget, Stringmethod)
{// Omitted. For details, see the clr source code} publicstaticDelegateCreateDelegate (Typetype, Objecttarget, Stringmethod)
{// Omitted. For details, see the clr source code} publicstaticDelegateCreateDelegate (Typetype, Typetarget, Stringmethod)
{// Omitted. For details, refer to the clr source code.} publicstaticDelegateCombine (paramsDelegate [] delegates) {} invoke (Delegatesource, Delegateb: delegate {privateObject_invocationList; protectedMulticastDelegate (Objecttarget, Stringmethod): base (target, method) {} protectedMulticastDelegate (Typetarget, Stringm Ethod): base (target, method) {}} from the source code, we can see that the Delegate class provides several overloaded static methods: CreateDelegate. the return value of the method is the Delegate type. If it is an instance method, the object reference is passed to it. If it is a static method, the object type is passed in.
PublicdelegateintDelegateCaculate (inta, intb); publicclassCaculate {publicintAdd (intnum1, intnum2)
{Returnnum1 + num2;} publicstaticintSubtract (intnum1, intnum2)
{Returnnum2-num1;} classProgram {staticvoidMain (string [] args)
{Caculatecaculate = newCaculate (); TypetypeCaculate = typeof (Caculate); TypetypeDelegate = typeof (DelegateCaculate); authorization = (DelegateCaculate) Delegate. createDelegate (typeDelegate, caculate, "Add"); DelegateCaculatesubtract = (DelegateCaculate) Delegate. createDelegate (typeDelegate, typeCaculate, "Subtract"); Console. writeLine ("add:" + add (10, 20); Console. writeLine ("subtract:" + subtract (10, 20); Console. ReadLine ();} CreateDelegate needs to retrieve the method handle by traversing metadata. C # Syntax provides a more convenient way to call the delegate. You can simply define the method by the type name or object name, and you do not need to traverse the metadata, C # the compiler uses the ldftn or ldw.ftn operator of the bottom-layer rule to obtain the method address, which is much faster than CreateDelegate. The above Main method can be rewritten
StaticvoidMain (string [] args)
{DelegateCaculateadd = newDelegateCaculate (newCaculate (). Add); DelegateCaculatesubtract = newDelegateCaculate (Caculate. subtract); Console. writeLine ("add:" + add (10, 20); Console. writeLine ("subtract:" + subtract (10, 20); Console. readLine ();} can put multiple delegate objects into the delegate object array. Once called, CLR will traverse the delegate array and call it one by one.
PublicdelegatevoidDelegateCaculate (inta, intb); publicclassCaculate {publicstaticvoidAdd (intnum1, intnum2)
{Console. WriteLine (num1 + num2);} publicstaticvoidSubtract (intnum1, intnum2)
{Console. WriteLine (num2-num1);} classProgram {staticvoidMain (string [] args)
{DelegateArray (newDelegateCaculate (Caculate. Add), newDelegateCaculate (Caculate. Subtract); Console. ReadLine ();} terminal (DelegateCaculatea, DelegateCaculateb)
{DelegateCaculatedelChain = null delChain = (DelegateCaculate) Delegate. combine (delChain, a); delChain = (DelegateCaculate) Delegate. combine (delChain, B); delChain (10, 20);} C # provides a more convenient syntax to add the delegate object to the delegate array. You can modify the preceding DelegateArray method in this way,
StaticvoidDelegateArray (DelegateCaculatea, DelegateCaculateb)
{DelegateCaculatedelChain = null delChain + = a; delChain + = B; delChain (10, 20);} when the execution (DelegateCaculate) Delegate. in Combine (delChain, a), because only one a object exists in the delegate array, delChain simply points to. as follows:
When the execution (DelegateCaculate) Delegate. combine (delChain, B) is because the delegate array already has two objects. A new MulticastDelegate object is generated to direct delChain to it, and _ invocationList points to a delegate array object, as follows:
If another delegate object is added, a new MulticastDelegate object is generated to point the delChain to the new object. The original object is waiting for the garbage collector to recycle. You can view the CLR source code, the NewMulticastDelegate method is called every time a delegate object is added. The return value of this method is MulticastDelegate.
Delegation and Interface
Interfaces and delegates have the ability to call specific methods, so they are very similar in this regard. However, the type declaration of the target method must be compatible with the interface, and the delegate can be called by any type, as long as the target method signature of the type matches the delegate signature.
So when to use the delegate and when to use the interface? msdn summarized it very well and I pasted it directly,
Delegation is useful in the following scenarios:
1. Call a single method.
2. A class requires multiple implementations of method specifications.
3. You want to allow static methods to be standardized.
4. Design Patterns for similar events.
5. The caller does not need to know or obtain the object of the method that matches the delegate signature.
6. The implemented provider only needs to implement the "distribution" Specification for a few selected components.
7. A combination of required methods.
Interfaces are useful in the following scenarios:
1. define a set of related methods.
2. Classes are generally only implemented once.
3. The caller of an interface wants to convert the interface type to another interface or class.