天天看點

【.NET】反射

什麼是反射?

反射是.net的一種重要機制,通過反射在運作時擷取程式(exe)或程式集(dll)中每一個類型(包含類,結構,委托,接口,枚舉等)的成員和成員的資訊,還可以建立這些類型的對象 。(簡單的說,有了反射,你就可以通過程式和程式集擷取你想要的一切資訊和資源。。。)

如何使用反射?

  1. 反射的命名空間
    •  System.Reflection
    • System.Type
    • System.Reflection.Assembly
  2. 加載程式集
    • 方法1:  将dll或exe拷貝至目前項目的運作程式所在目錄下,如:“Test.dll"
    •                Assembly assembly = Assembly.Load("Test");
    • 方法2:  直接加載具體路徑下的程式集,如:”D:\Test\Test.dll“
    •               Assembly assembly = Assembly.LoadFrom(@"D:\Test\Test.dll");
  3. 擷取類型
    • 方法1: 通過 已知的類名擷取類型,如:“Test.CTest"
    •               Type type = assembly.GetType("Test.CTest");  
    • 方法 2: 通過程式集周遊所有的類型
    • foreach(var type in assembly.GetTypes())
      {
      	//代碼段
      }
                 
  4. 反射建立對象(通過類型建立執行個體)
    •                 object obj = Activator.CreateInstance(type);
  5. 反射調用執行個體方法,靜态方法,重載方法
    • 方法一: 通過已知方法名調用方法,如:方法“void Func()"
    •                 MethodInfo method = type.GetMethod("Func");
    •                 method.Invoke(obj, null);
    • 方法二: 周遊方法再調用 
    • foreach(var method in type.GetMethods())
      {
            method.Invoke(obj, null);  //此示例調用的是類的無參公共成員方法 
      }
                 
  6. 反射調用私有方法,泛型方法
    • 反射私有方法:
    • 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" }); 
    	}
               
  7. 反射字段和屬性
    • 反射字段,如: 有字段 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)); 
      	} 
      }
                 

繼續閱讀