C# 反射/映射學習

來源:互聯網
上載者:User

標籤:style   blog   color   ar   使用   sp   檔案   div   on   

反射其實就是為了能夠在程式運行期間動態載入一個外部的DLL集合,然後通過某種辦法找到這個DLL集合中的某個空間下的某個類的某個成員(通過反射可以訪問該類所包含的所有成員,不論成員是公有還是私人)

1.運用反射調用其它程式集中的方法:   
  假設另一個工程中的所有類都編譯到一個dll檔案中了,在這很多的類當中,有一個類叫StringUtil,名稱空間在HSMP.CommonBasic.Common 代碼如下 :

namespace lab.CommonBasic.Common{    class StringUtil    {        public double GetSum(double x, double y)        {            return x + y;        }       }}

編譯後dll檔案的存放路徑是:D:\Test\HSMP.CommonBasic.dll   
  現在的問題是,如何通過程式調用該dll檔案中的GetSum方法   
  大概有以下幾步:

//這裡要用LoadFrom,只有在本工程裡添加了該dll的引用後才可以使用Load       Assembly objAss = Assembly.LoadFrom(@"D:\Test\HSMP.CommonBasic.dll");    //HSMP.CommonBasic.Common.StringUtil類的全路徑       Type t = objAss.GetType("HSMP.CommonBasic.Common.StringUtil");    //動態產生類StringUtil的執行個體       object obj = System.Activator.CreateInstance(t);    //參數資訊,GetSum需要兩個int參數       System.Type[] paramTypes = new System.Type[2];    paramTypes[0] = System.Type.GetType("System.Int32");    paramTypes[1] = System.Type.GetType("System.Int32");    //找到對應的方法       MethodInfo p = t.GetMethod("SayHello", paramTypes);    // 也可以不給型別參數,下面調用時給實參就可以    MethodInfo p = t.GetMethod("SayHello");    //參數值,如果所調用的方法沒有參數,不用寫這些       Object[] parameters = new Object[2];    parameters[0] = 3;    parameters[1] = 4;    //如果沒有參數,寫null即可。     object objRetval = p.Invoke(obj, parameters);

 通過代碼可以看出反射其實很簡單。就是動態類型載入。

   

    以上我們用反射對靜態類型做載入,但如果類是個範型類該怎麼辦呢?其實方法大同小異,只是擷取到類型時需要設定一下實際要使用的類型即可,先看範型類定義:

namespace lab.CommonBasic.Common{    class StringUtil<T,U>    {        public string GetSum(T x, U y)        {            return x + " and " + y;        }       }}

再看反射操作:

... 前面代碼相同    //HSMP.CommonBasic.Common.StringUtil類的全路徑(範型類最後用 `2 標示需要2個範型型別參數)       Type t = objAss.GetType("HSMP.CommonBasic.Common.StringUtil`2");    // 這一步很重要,設定實際的範型類型    t = t.MakeGenericType(new Type[2] { typeof(string), typeof(string) });    //動態產生類StringUtil的執行個體       object obj = System.Activator.CreateInstance(t);    ... 後面代碼相同

還有一種情況,如果類是常類,但方法是範型方法改怎麼辦?非常簡單:

... 前面代碼相同    //HSMP.CommonBasic.Common.StringUtil類的全路徑(範型類最後用 `2 標示需要2個範型型別參數)       Type t = objAss.GetType("HSMP.CommonBasic.Common.StringUtil`2");    // 這一步要去掉,因為類不是泛型類所以不能給類設定範型類型    //t = t.MakeGenericType(new Type[2] { typeof(string), typeof(string) });     ... 中間代碼相同     // 區別在這裡,把類層級的範型類型設定放到方法層級就可以了。    MethodInfo p = t.GetMethod("SayHello");    MethodInfo p = p.MakeGenericMethod(new Type[2] { typeof(string), typeof(string) });    ... 後面代碼相同

2.動態載入, 更改, 增加...某個程式集
  下面例子中, ChangeValue類的myValue本是私人欄位, 
  一般情況下在類外部是不能改它的值的, 但利用反射就能直接存取私人欄位而不需要通過封裝器

class ChangeValue{    // 這是私人欄位    private string myValue;    // 一般只有通過這樣的公用屬性外面才可能訪問私人欄位    public ChangeValue(string str)    {        myValue = str;    }    public void WriteLine()    {        Console.WriteLine("MyValue is: " + myValue);    }}class Test{    public static void Main(string[] args)    {        // 正常訪問        ChangeValue cv = new ChangeValue("old value");        cv.WriteLine();        //反射的方法直接存取私人欄位        Type t = cv.GetType();        //得到私人欄位對象並賦值        FieldInfo field = t.GetField("myValue", BindingFlags.NonPublic | BindingFlags.Instance);        field.SetValue(cv, "new value");        //輸出的是新值 "new value"        cv.WriteLine();    }}

 

 打個比方, 你要寫一個播放器, 要支援如mp3, wmv, avi...等格式, 你還希望使用者能自己安裝一個新的格式, 也就是我們常說的外掛程式.
在實現這些, 可能你要將每種格式都寫成單個的解碼程式集, 如 mp3.dll, wmv.dll, avi.dll....  這樣當播放時, 根據副檔名去動態調用相應的解碼程式集, 那麼這時你就得用反射去動態載入這些dll了.如: Assembly.LoadFile ("...avi.dll"), 然後通過反射可以用avi.dll裡面定義的類了.

C# 反射/映射學習

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.