天天看點

[C#]如何通路及調用類中私有成員及方法

原文: [C#]如何通路及調用類中私有成員及方法

本文為原創文章、源代碼為原創代碼,如轉載/複制,請在網頁/代碼處明顯位置标明原文名稱、作者及網址,謝謝!

開發工具:VS2017

語言:C#

DotNet版本:.Net FrameWork 4.0及以上

系統:Win10 X64

一、首先建立一個控制台APP,并命名為ConsoleApp,如下圖所示:

[C#]如何通路及調用類中私有成員及方法
二、建立一個Person類,并在類裡面添加兩個成員,一個是name字段,另外一個是Display方法,該方法帶有一個“字首”輸入參數prefix,用于加在name字段前面,如下代碼所示:

class Person
    {
        string name;
        void Display(string prefix)
        {
            Console.WriteLine($"{prefix},{name}");
        }
    }      

三、将System.Reflection引用進來,這裡是本随筆的關鍵所在,如下圖所示:

using System.Reflection;      

四、如何設定及通路name字段?在這裡我們使用反射技術,使用Type類裡的反射機制進行通路,

1)公用部分,具體代碼如下:

Person person = new Person();
 Type type = typeof(Person);
 BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
 FieldInfo fInfo = type.GetField("name", flags);      

2)設定name字段,設定方法如下代碼所示:

fInfo.SetValue(person,"CNXY");      

3)通路name字段,通路方法如下代碼所示:

var name = fInfo.GetValue(person);      

4)name字段結果如下:

[C#]如何通路及調用類中私有成員及方法

說明:

BindingFlags.NonPublic:搜尋非公有方法的成員;

BindingFlags.Instance:搜尋成員執行個體,包括字段及方法等。

五、如何通路Display私有方法?同樣,借用第四部分代碼(person及flags),具體代碼如下:

MethodInfo mInfo = type.GetMethod("Display",flags);
mInfo.Invoke(person, new object[] { "Hello" });      

輸出結果如下:

[C#]如何通路及調用類中私有成員及方法

Invoke用于調用方法,後面的參數使用數組的方法,如有一個參數,則輸入一個參數的object數組,如有多個參數,則輸入多個參數的object數組。

六、源代碼如下:

https://pan.baidu.com/s/1qXVorQ8          

七、實際用處,System.Windows.Forms下面有一個類,名叫NotifyIcon,其設定的Text隻能是63個字元,所想輸入大于63個字元,如下設定方法是行不通的,代碼如下:

NotifyIcon ni = new NotifyIcon();
ni.Text = "64個字元(實際有64個字元,這裡并沒有達到個數,僅作展示)";      

那麼,我們必須另外的方法來繞過NotifyIcon的限制,這裡使用了反射技術(也就是以上所說的),代碼如下:

NotifyIcon ni = new NotifyIcon();
string text = "大于63個字元,小于127個字元的字元串";
if (text.Length >= 128) throw new ArgumentOutOfRangeException("Text limited to 127 characters");
Type t = typeof(NotifyIcon);
BindingFlags hidden = BindingFlags.NonPublic | BindingFlags.Instance;
t.GetField("text", hidden).SetValue(ni, text);
if ((bool)t.GetField("added", hidden).GetValue(ni)) t.GetMethod("UpdateIcon", hidden).Invoke(ni, new object[] { true });      

以上的限制個數為大于63個,小于127個。

繼續閱讀