在還不太熟悉反射的昨天 ,以為反射很神秘 ,在網上到處找答案 .今天找了段代碼敲了一下 ,茅塞頓開 ! 其實反射也就那麼簡單的一回事 ! 反射是一種機制 , 通過這種機制我們可以知道一個未知類型的類型信息 .比如 ,有一個對象 a, 這個 對象不是我們定義的,也許是通過網路捕捉到的,也許是使用泛型定 ...
在還不太熟悉反射的昨天 ,以為反射很神秘 ,在網上到處找答案 .今天找了段代碼敲了一下 ,茅塞頓開 !
其實反射也就那麼簡單的一回事 !
反射是一種機制 , 通過這種機制我們可以知道一個未知類型的類型信息 .比如 ,有一個對象 a, 這個
對象不是我們定義的,也許是通過網路捕捉到的,也許是使用泛型定義的,但我們想知道這個對象的
類型信息,想知道這個對象有哪些方法或者屬性什麼的.甚至我們想進一步調用這個對象的方法.關
鍵是現在我們只知道它是一個對象,不知道它的類型,自然不會知道它有哪些方法等信息.這時我們
該怎麼辦?反射機制就是解決這麼一個問題的. 通過反射機制我們可以知道未知類型對象的類型信息.
再比如,我們有一個 dll 文件,我們想調用裡面的類.現在假設這個 dll 文件的類的定義,數量
等不是固定的,是經常變化的.也許某一天你要在這個 dll 裡面增加一個類定義.也許你覺得這沒什
麽問題,現在關鍵是我們在另一個程式集裡面要調用這個 dll ,這是我們的程式必須能夠適應這個 dll
的變化,也就是說即使改變了 dll 文件的定義也不需要改變我們的程式集.這時候我們就會使用一個
未知 dll .我們該怎麼辦?同樣,反射機制幫助了我們,我們可以通過反射來實現.
說白了,反射就是能知道我們未知類型的類型信息這麼一個東西.沒什麼神秘可講!
今天我先講一個獲得程式集信息的例子.
下麵我們來舉一個例子. 例子的思路是這樣的: 我們有一個 dll. 該 dll 裡面有許多關於運動的類. 每
一個類記錄了一種體育運動的信息.我們在另外一個程式裡面要知道這個 dll 的信息:(如果你還不
能明白我的意思,請耐心的照我的步驟把這個過程走一變!)
第一步:我們建一個文件 Sport.cs. 內容如下:
using System; public abstract class Sport { protected string name; public abstract string GetDuration(); public abstract string GetName(); }
咱們用命令" csc /t:library Sport.cs "編譯它.
第二步,我們再建一個名為 SomeSports.cs 的文件,內容如下:
using System; public class Football : Sport { public Football() { name = "Football"; } public override string GetDuration() { return "four 15 minute quarters"; } public override string GetName() { return name; } } public class Hockey : Sport { public Hockey() { name = "Hockey"; } public override string GetDuration() { return "three 20 minute periods"; } public override string GetName() { return name; } } public class Soccer : Sport { public Soccer() { name = "Soccer"; } public override string GetDuration() { return "two 45 minute halves"; } public override string GetName() { return name; } }
下麵我們用命令" csc /t:library /r:Sport.dll SomeSports.cs "編譯該文件.
現在我們有了我們的運動信息 dll 文件.現在我們想通過程式知道裡面有哪些類.請進入最後一
步:
第三步:我們創建文件 AssemblyDemo .cs".內容如下:
using System; using System.Reflection; public class AssemblyDemo { public static void Main(string[] args) { int i, j; //========================== //First the command line arguments are evaluated.if there isn't //at least one,a usage message is printed //================================= if (args.GetLength(0) < 1) { Console.WriteLine("usage is AssemblyDemo<library_name>"); } else { //======================== // An Assembly object is obtained from the command line argument //======================== Assembly assembly = Assembly.LoadFrom(args[0]); Type[] types = assembly.GetTypes(); Console.WriteLine(assembly.GetName().Name + "contains the following types"); for (i = 0; i < types.GetLength(0); ++i) { Console.WriteLine("\r(" + i + ") " + types[i].Name); } i = types.Length - 1; Console.Write("make selection(0-" + i + ");"); j = Convert.ToInt32(Console.ReadLine()); Console.WriteLine(); if (types[j].IsSubclassOf(typeof(Sport))) { ConstructorInfo ci = types[j].GetConstructor(new Type[0]); Sport sport = (Sport)ci.Invoke(new Object[0]); Console.WriteLine(sport.GetName() + "has" + sport.GetDuration()); } else { Console.WriteLine(types[j].Name + "is not a sub-class of Sport"); } } } }
咱們用命令" csc /r:Sport.dll AssemblyDemo.cs "編譯該文件.
下麵我們用"A ssemblyDemo SomeSports.dll "運行該程式.
進一步程式要求我們輸入選項, 咱們輸入1,就顯示了結果: Hockeyhasthree 20 minute periods.
好了,今天就到這裡了,下麵我將進一步說明如何用反射機制訪問對象的類型信息
我不想在這裡過多的描述反射的概念。我還是用我自己覺得最簡單、最直接的語言來描述反射
——“反射就是一種機制,通過這種機制,我們能知道一些位知程式集的詳細信息!”;通過上一篇
我們已經學會如何得到一個未知程式集的相關信息, 接下來我要講的是如何知道未知程式模塊的信息:
模塊信息是通過 Module 類訪問的。下麵通過一個類子,講解下 Module 類的使用,如果你是
一個用心的程式員,應該瞭解下 Module 的詳細信息。
下麵我們寫一個新的文件 ModuleDemo.cs 。內容如下:
// 編譯命令 csc /r:Sport.dll ModuleDemo.cs
using System; using System.Reflection; public class ModuleDemo { public static void Main(string[] args) { //======================= // Am Module object is obtained representing the // SomeSports.dll library file //======================= Assembly assembly = Assembly.Load("SomeSports"); Module module = assembly.GetModule("SomeSports.dll"); //====================== //Search the module for the type named "Football" Type[] types = module.FindTypes(Module.FilterTypeName, "Football"); if (types.Length != 0) { ConstructorInfo ci = types[0].GetConstructor(new Type[0]); Sport sport = (Sport)ci.Invoke(new Object[0]); Console.WriteLine(sport.GetName() + " has " + sport.GetDuration()); } else { Console.WriteLine("type not found"); } } }
我們用 csc /r:Sport.dll ModuleDemo.cs 編譯,然後用 MouduleDemo 運行程式就能看到如下輸
出:Football has four 15 minute quarters 。
關於 C# 反射的基礎知識,還有一個知識點就是訪問未知對象的類型信息。
註:內容來源於網路