反射的定義
反射提供了描述程序集、模塊和類型的對象(Type 類型)。 可以使用反射動態創建類型的實例,將類型綁定到現有對象,或從現有對象獲取類型並調用其方法或訪問其字段和屬性。 如果代碼中使用了特性,可以利用反射來訪問它們。------摘自MSDN
自我理解
看到反射二字,自然而然的會想到,小時候拿着一面鏡子,反射陽光玩。其實
反射就好比一面鏡子,通過它我們能在不顯示引用程序集的情況下,一窺程序集內的“風景”。
利用好反射這把利器,我們在開發中就能體會到荀老夫子所言的,君子性非異也,善假於物也
本文主要包括以下四節:
通過反射調用類的構造函數(有參/無參)
通過反射調用類的靜態方法(有參/無參)
通過反射調用類的非靜態方法(有參/無參)
通過反射調用類的含有ref參數的方法
代碼示例:

1 namespace TestDLL 2 { 3 using System.Linq; 4 5 public class TestClass 6 { 7 private int _priValue; 8 9 //無參構造函數 10 public TestClass() 11 { 12 this._priValue = 9; 13 } 14 15 //有參構造函數 16 public TestClass(int i) 17 { 18 this._priValue = i; 19 } 20 21 //無參方法 22 public int Add() 23 { 24 return ++this._priValue; 25 } 26 27 //ref參數的方法 28 public void Exchange(ref int a, ref int b) 29 { 30 int temp = b; 31 b = a; 32 a = temp; 33 } 34 35 // 靜態有參方法 36 public static string SayHi(string name) 37 { 38 return "Hi~ " + name; 39 } 40 41 public static int AddValue(int[] objsInts) 42 { 43 int temp = 0; 44 if (objsInts != null) 45 { 46 temp += objsInts.Sum(); 47 } 48 return temp; 49 } 50 } 51 }
通過反射調用代碼示例:
static void Main(string[] args) { //加載程序集(dll文件地址),使用Assembly類 Assembly testDll = Assembly.LoadFile(Environment.CurrentDirectory + "\\TestDLL.dll"); //獲取類型,參數(名稱空間+類) Type testClass = testDll.GetType("TestDLL.TestClass"); //創建實例 var instance = testDll.CreateInstance("TestDLL.TestClass"); //調用無參構造函數 ConstructorInfo noParamConstructor = testClass.GetConstructor(Type.EmptyTypes); object testClassObject = noParamConstructor.Invoke(new object[] { }); //調用有參構造函數 ConstructorInfo paramConstructor = testClass.GetConstructor(new Type[] { Type.GetType("System.Int32") }); object testClassObject2 = paramConstructor.Invoke(new object[] { 2 }); #region 調用非靜態方法 MethodInfo addMethod = testClass.GetMethod("Add"); object addValue = addMethod.Invoke(instance, new object[] { }); #endregion #region 調用靜態有參方法 MethodInfo sayHiMethod = testClass.GetMethod("SayHi"); object sayHi = sayHiMethod.Invoke(null, new object[] { "jason" }); #endregion #region 調用含有ref參數的方法 MethodInfo exchange = testClass.GetMethod("Exchange"); var objs = new object[2]; objs[0] = 5; objs[1] = 6; Console.WriteLine("objs[0]={0}\nobjs[1]={1}", objs[0], objs[1]); object retValue = exchange.Invoke(instance, objs); #endregion #region 調用參數為數組的方法 MethodInfo addValueInfo = testClass.GetMethod("AddValue"); var ints = new int[] {1, 2, 3, 4, 5}; object obj = addValueInfo.Invoke(null, new object[] {ints}); #endregion Console.WriteLine("MethodInfo.Invoke() Example\n"); Console.WriteLine("TestClass.Add() returned: {0}", addValue); Console.WriteLine("TestClass.SayHi() returned:{0}", sayHi); Console.WriteLine("TestClass.Exchange(ref int a,ref int b) returned:{0}", retValue); Console.WriteLine("objs[0]={0}\nobjs[1]={1}", objs[0], objs[1]); Console.WriteLine("AddValue(int[] objsInts) result:{0}", obj); }
在此對代碼中紅色加粗的方法做注(摘自MSDN):
MethodBase.Invoke 方法 (Object, Object[])
使用指定的參數調用當前實例所表示的方法或構造函數。
語法
public Object Invoke(
Object obj,
Object[] parameters
)
參數
obj
類型:System.Object
對其調用方法或構造函數的對象。 如果方法是靜態的,則忽略此參數。 如果構造函數是靜態的,則此參數必須為 null 或定義該構造函數的類的實例。
若要使用其 MethodInfo 對象來調用靜態方法,請將 null 傳遞給 obj。
parameters
類型:System.Object[]
調用的方法或構造函數的參數列表。 這是一個對象數組,這些對象與要調用的方法或構造函數的參數具有相同的數量、順序和類型。 如果沒有任何參數,則 parameters 應為 null。
如果此實例所表示的方法或構造函數采用 ref 參數(在 Visual Basic 中為 ByRef),使用此函數調用該方法或構造函數時,該參數不需要任何特殊屬性。 如果此數組中的對象未用值來顯式初始化,則該對象將包含該對象類型的默認值。 對於引用類型的元素,該值為 null。 對於值類型的元素,該值為 0、0.0 或 false,具體取決於特定的元素類型。
返回值
類型:System.Object
一個對象,包含被調用方法的返回值,如果調用的是構造函數,則為 null。