C#如何判斷委托是實例方法還是靜態方法


一. 委托的分類

通過用什么類型的方法來聲明為委托,可以分為兩類:

1. 委托靜態方法:把一個靜態方法給委托

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

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

二. 原理部分

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

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

// _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的屬性,我們可以看到一個屬性 Target

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

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

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

可以看到這邊有一個字段 _methodPtrAux,這是一個IntPtr類型的指針,可以看到注釋可以看出,當把一個靜態方法給委托的時候,將會返回一個 null,如果是一個實例方法的時候,將會返回當前方法所在的實例對象(this)

// 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說明是實例方法的委托。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM