在還不太熟悉反射的昨天,以為反射很神秘,在網上到處找答案.今天找了段代碼敲了一下,茅塞頓開!其實反射也就那麼簡單的一回事!
反射是一種機制,通過這種機制我們可以知道一個未知類型的類型信息.比如,有一個對象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"編譯該文件.
下面我們用"AssemblyDemo SomeSports.dll"運行該程序.
進一步程序要求我們輸入選項,咱們輸入1,就顯示了結果:Hockeyhasthree 20 minute periods.
好了,今天就到這裡了,下面我將進一步說明如何用反射機制訪問對象的類型信息.