.net反射機制為創建對象和調用其他方法提供了替代方案。比如為了提高代碼的靈活性。但是問題確是我們要編寫更多的代碼來實現。
使用反射機制是有一些缺點的。其最大的缺點就是編譯器無法對對象進行類型檢查,此時IDE的智能感知將無能為力。但是他的真正優勢又在什麼地方呢?它提供了一種手段,將指定具體類推遲到了運行時刻。
使用反射機制調用方法的四步曲:
1 加載程序集
2 獲取類的類型
3 創建該類的實例
4 調用該實例的方法
System.Reflection.Assembly類中有兩個靜態方法Assembly.Load(string assemblyName)和Assembly.LoadFrom(string fileName)來把程序集加載到應用程序序域中。
PS:在。NET中當一個對象被創建時,幕後到底發生了什麼?當我們運行某一個應用程序時,.NET CLR會首先創建一個應用程序域來容納這個應用程序,接著將應該引用的程序集加載到應用程序域中。其中MSCorLib.dll是一個程序集,它包含了很多系統命名空間及其子命名空間中的類:System;System.Text,System.IO等。該程序集合中。然後CLR加載正在運行的應用程序所屬的程序集。
DEMO:
<一>
(1)namespace ClassLibrarySport
{
publicabstractclass Sport
{
protectedstring name;
publicabstractstring GetName();
publicabstractstring GetDuration();
}
}
= = = = = == = == = == = == = == = == = == = == = == = == = == = == = == = == = == = =
(2)namespace ClassLibrarySomeSports//該項目添加了對(1)的引用
{
publicclassFootball : ClassLibrarySport.Sport
{
public Football()
{
name = "Football";
}
publicoverridestring GetName()
{
return name;
}
publicoverridestring GetDuration()
{
return"four 15 minute quarters";
}
}
}
= = = = = == = == = == = == = == = == = == = == = == = == = == = == = == = == = == = =
(3)namespace ConsoleAssemblyTest//該項目添加了對(1)的引用
{
classProgram
{
staticvoid Main(string[] args)
{
Assembly assembly =Assembly.LoadFrom(@"E:"ClassLibrarySomeSports"
bin"Debug"ClassLibrarySomeSports.dll");
Type[] types = assembly.GetTypes();
Console.WriteLine("Get Type From ClassLibrarySomeSports.dll:");
for (int i = 0; i < types.Length; i++)
{
Console.WriteLine(types[i].Name);
}
//使用GetConstructor()方法獲取對應類型的構造器,從而構造出該類型的對象
Console.WriteLine("Use Method GetConstructor():");
ConstructorInfo ci = types[0].GetConstructor(newType[0]);
ClassLibrarySport.Sport sport = (ClassLibrarySport.Sport)ci.Invoke(newobject[0]);
Console.WriteLine(sport.GetName() +" has " + sport.GetDuration());
//使用Activator.CreateInstance()方法構造出該類型的對象
//使用assembly.CreateInstance()返回為null,??
Console.WriteLine("Use Method CreateInstance():");
ClassLibrarySport.Sport sport1 = (ClassLibrarySport.Sport)
Activator.CreateInstance(types[0]);
Console.WriteLine(sport1.GetName() +" has " + sport1.GetDuration());
//反射指定類型中的名稱為“GetDuration”的方法,通過Invoke()方法執行該方法
object objSport =Activator.CreateInstance(types[0]);
MethodInfo method = types[0].GetMethod("GetDuration");
object o = method.Invoke(objSport,newobject[0]);
Console.WriteLine(oasstring);
Console.Read();
}
}
}
= = = = = == = == = == = == = == = == = == = == = == = == = == = == = == = == = == = =
Output:
Get Type From ClassLibrarySomeSports.dll:
Football
Use Method GetConstructor():
Football has four 15 minute quarters
Use Method CreateInstance():
Football has four 15 minute quarters
four 15 minute quarters
<二>
1 創建用於反射使用的DLL
新建一個C#類庫項目,拷貝源代碼如下,編譯生成DLL(假如DLL的文件名是TestReflect.dll)
1using System;
2
3namespace Webtest
4{
5 /// <summary>
6 /// ReflectTest 的摘要說明。
7 /// </summary>
8 public class ReflectTest
9 {
10 public ReflectTest()
11
12
13 public string WriteString(string s)
14
17
18 /// <summary>
19 /// dsajkjflasjdfalksdjfaskfd
20 /// </summary>
21 /// <param name="s"></param>
22 /// <returns></returns>
23 public static string WriteName(string s)
24
27
28 public string WriteNoPara()
29
32 }
33}
34
35
36
2 應用於反射的例子
在ASPNET頁面中加入以下函數:
1public void test1()
2 {
3 System.Reflection.Assembly ass;
4 Type type ;
5 object obj;
6 try
7 {
8 ass = System.Reflection.Assembly.LoadFile(@"d:\TestReflect.dll");
9 type = ass.GetType("Webtest.ReflectTest");//必須使用名稱空間+類名稱
10 System.Reflection.MethodInfo method = type.GetMethod("WriteString");//方法的名稱
11 obj = ass.CreateInstance("Webtest.ReflectTest");//必須使用名稱空間+類名稱
12 string s = (string)method.Invoke(obj,new string[]{"jianglijun"}); //實例方法的調用
13
14 Response.Write(s+"<br>");
15 method = type.GetMethod("WriteName");//方法的名稱
16 s = (string)method.Invoke(null,new string[]{"jianglijun"}); //靜態方法的調用
17 Response.Write(s+"<br>");
18
19 method = type.GetMethod("WriteNoPara");//無參數的實例方法
20 s = (string)method.Invoke(obj,null);
21 Response.Write(s+"<br>");
22 method = null;
23 }
24 catch(Exception ex)
25 {
26 Response.Write(ex+"<br>");
27 }
28 finally
29 {
30 ass = null;
31 type = null;
32 obj = null;
33 }
34 }