C#反射(一)
在還不太熟悉反射的昨天,以為反射很神秘,在網上到處找答案.今天找了段代碼敲了一下,茅塞頓開!其實反射也就那麼簡單的一回事!
反射是一種機制,通過這種機制我們可以知道一個未知類型的類型資訊.比如,有一個對象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.
好了,今天就到這裡了,下面我將進一步說明如何用反射機制訪問對象的類型資訊.
在還不太熟悉反射的昨天,以為反射很神秘,在網上到處找答案.今天找了段代碼敲了一下,茅塞頓開!其實反射也就那麼簡單的一回事!
反射是一種機制,通過這種機制我們可以知道一個未知類型的類型資訊.比如,有一個對象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.
好了,今天就到這裡了,下面我將進一步說明如何用反射機制訪問對象的類型資訊.