一. 委托的分類
通過用什么型別的方法來宣告為委托,可以分為兩類:
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說明是實體方法的委托,
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/101924.html
標籤:C#
下一篇:C# 使用GDI繪制雷達圖
