C#如何判斷委託是實例方法仍是靜態方法

一. 委託的分類

經過用什麼類型的方法來聲明爲委託,能夠分爲兩類:函數

1. 委託靜態方法:把一個靜態方法給委託測試

2. 委託實例方法:把一個實例對象的成員方法給委託this

(這兩個名字是博主取的,可能不是很專業只是爲了好區分)spa

二. 原理部分

委託是將函數指針和實例對象打包在一塊兒的類,它有兩個重要的成員,一個用來保存實例對象,一個用來保存函數的指針。從源碼中咱們能夠查看System.Delegate,以下:指針

1. 將會調用方法所在的對象code

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

2. 將會調用的方法指針對象

// _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;

另外,咱們查看System.Delegate的屬性,咱們能夠看到一個屬性 Targetblog

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

來看一下這個 GetTarget() 方法的功能rem

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

能夠看到這邊有一個字段 _methodPtrAux,這是一個IntPtr類型的指針,能夠看到註釋能夠看出,當把一個靜態方法給委託的時候,將會返回一個 null,若是是一個實例方法的時候,將會返回當前方法所在的實例對象(this)get

// 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;

三. 測試代碼

測試類 Test.cs:

public class Test
{
    /// <summary>
    /// 實例方法
    /// </summary>
    public void ShowHelloWorld1()
    {
        Console.WriteLine("Hello World! -- 1");
    }

    /// <summary>
    /// 靜態方法
    /// </summary>
    public static void ShowHelloWorld2()
    {
        Console.WriteLine("Hello World! -- 2");
    }
}

委託聲明:

public delegate void ShowHelloWorldMethod();

上端測試代碼:

//聲明測試對象
Test test = new Test();

//構造實例方法的委託
ShowHelloWorldMethod del = test.ShowHelloWorld1;

//判斷一下Target是否是指向方法所在的對象
Console.WriteLine(del.Target is Test);//True

//調用一下
((Test)del.Target).ShowHelloWorld1();//Hello World! -- 1

//構造靜態方法的委託
ShowHelloWorldMethod del2 = Test.ShowHelloWorld2;

//判斷一下Target是否是null
Console.WriteLine(del2.Target == null);//true

測試結果符合咱們的預期:

 

 

四. 總結

若是委託的Target屬性爲null說明是靜態方法的委託,若是委託的Target屬性不爲null說明是實例方法的委託。

相關文章
相關標籤/搜索