什麼是反射?
反射是.net的一種重要機制,通過反射在運作時擷取程式(exe)或程式集(dll)中每一個類型(包含類,結構,委托,接口,枚舉等)的成員和成員的資訊,還可以建立這些類型的對象 。(簡單的說,有了反射,你就可以通過程式和程式集擷取你想要的一切資訊和資源。。。)
如何使用反射?
- 反射的命名空間
- System.Reflection
- System.Type
- System.Reflection.Assembly
- 加載程式集
- 方法1: 将dll或exe拷貝至目前項目的運作程式所在目錄下,如:“Test.dll"
- Assembly assembly = Assembly.Load("Test");
- 方法2: 直接加載具體路徑下的程式集,如:”D:\Test\Test.dll“
- Assembly assembly = Assembly.LoadFrom(@"D:\Test\Test.dll");
- 擷取類型
- 方法1: 通過 已知的類名擷取類型,如:“Test.CTest"
- Type type = assembly.GetType("Test.CTest");
- 方法 2: 通過程式集周遊所有的類型
-
foreach(var type in assembly.GetTypes()) { //代碼段 }
- 反射建立對象(通過類型建立執行個體)
- object obj = Activator.CreateInstance(type);
- 反射調用執行個體方法,靜态方法,重載方法
- 方法一: 通過已知方法名調用方法,如:方法“void Func()"
- MethodInfo method = type.GetMethod("Func");
- method.Invoke(obj, null);
- 方法二: 周遊方法再調用
-
foreach(var method in type.GetMethods()) { method.Invoke(obj, null); //此示例調用的是類的無參公共成員方法 }
- 反射調用私有方法,泛型方法
- 反射私有方法:
-
foreach(var method in type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public |BindingFlags.Instance|BindingFlags.Static)) { if (method.Name.Equals("Func1")) { method.Invoke(obj, null); //執行個體方法 需要傳入執行個體和參數,無參可傳入null } else if (method.Name.Equals("Func2")) { method.Invoke(null, new object[] { 100 }); //類方法的調用可以不用傳入執行個體 } }
- 反射泛型方法, 如:函數簽名 public void FuncGeneric<T>( T tParameter );
if(method.Name.Equals("FuncGeneric")) { MethodInfo methodTmp = method.MakeGenericMethod(typeof(string)); methodTmp.Invoke(obj, new object[] { "hello, kitty" }); }
- 反射字段和屬性
- 反射字段,如: 有字段 int iD, string name
foreach(var value in type.GetFields(BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Static| BindingFlags.Instance)) { if(value.Name.ToString().Equals("Name")) { value.SetValue(null, "Xiaowangba"); } else if(value.Name.ToString().Equals("ID")) { Console.WriteLine("Field ID={0}",value.GetValue(obj)); //如果是類字段 即可不用傳入執行個體,直接傳入null即可 } }
- 反射屬性,如: 有屬性 int Age{set;get;}
-
foreach(var property in type.GetProperties()) { if(property.Name.Equals("Age")) { Console.WriteLine("Age = {0}", property.GetValue(obj)); property.SetValue(obj, 18); Console.WriteLine("After SetValue: Age = {0}", property.GetValue(obj)); } }