How to determine whether a delegate is an instance method or a static method

Keywords: C#

I. classification of entrustment

There are two types of methods used to declare a delegate:

1. Delegate static method: delegate a static method to a delegate

2. Delegate instance method: delegate the member method of an instance object to the delegate

(these two names are taken by bloggers. They may not be very professional just to distinguish them.)

II. Principle part

Delegate is a class that packs function pointer and instance object together. It has two important members, one is used to save instance object and the other is used to save function pointer. From the source code, we can view System.Delegate as follows:

1. The object where the method will be called

// _target is the object we will invoke on
[System.Security.SecurityCritical]
internal Object _target;

2. Method pointer to be called

// _methodPtr is a pointer to the method we will invoke
// It could be a small thunk if this is a static or UM call
[System.Security.SecurityCritical]
internal IntPtr _methodPtr;

In addition, if we look at the properties of System.Delegate, we can see a property Target

public Object Target
{
    get
    {
        return GetTarget();
    }
}    

Take a look at the function of the GetTarget() method

[System.Security.SecuritySafeCritical]
internal virtual Object GetTarget()
{
    return (_methodPtrAux.IsNull()) ? _target : null;
}

You can see that there is a field ﹐ methodPtrAux here, which is a pointer of type IntPtr. You can see from the comments that when a static method is delegated, a null will be returned. If it is an instance method, the instance object (this) in which the current method is located will be returned

// In the case of a static method passed to a delegate, this field stores
// whatever _methodPtr would have stored: and _methodPtr points to a
// small thunk which removes the "this" pointer before going on
// to _methodPtrAux.
[System.Security.SecurityCritical]
internal IntPtr _methodPtrAux;

III. test code

Test class Test.cs:

public class Test
{
    /// <summary>
    /// Example method
    /// </summary>
    public void ShowHelloWorld1()
    {
        Console.WriteLine("Hello World! -- 1");
    }

    /// <summary>
    /// Static method
    /// </summary>
    public static void ShowHelloWorld2()
    {
        Console.WriteLine("Hello World! -- 2");
    }
}

Statement of entrustment:

public delegate void ShowHelloWorldMethod();

Upper test code:

//Declare test object
Test test = new Test();

//Construct delegation of instance method
ShowHelloWorldMethod del = test.ShowHelloWorld1;

//Judge Target Does it point to the object of the method
Console.WriteLine(del.Target is Test);//True

//Call it
((Test)del.Target).ShowHelloWorld1();//Hello World! -- 1

//To construct a delegate for a static method
ShowHelloWorldMethod del2 = Test.ShowHelloWorld2;

//Judge Target Is it right? null
Console.WriteLine(del2.Target == null);//true

The test results meet our expectations:

 

 

Four. Conclusion

If the Target property of the delegate is null, it indicates that it is the delegate of the static method. If the Target property of the delegate is not null, it indicates that it is the delegate of the instance method.

Posted by CodeJunkie88 on Thu, 21 Nov 2019 05:43:40 -0800