——博客園 老金最近想研究一下反射,先上網(wǎng)找了找資料,幾乎大部分都是照抄MSDN的內(nèi)容,生澀難懂,幾乎沒(méi)說(shuō),又找了找,發(fā)現(xiàn)一些強(qiáng)人的實(shí)例解析,才稍微有了點(diǎn)門(mén)道,個(gè)人感覺(jué),反射其實(shí)就是為了能夠在程序運(yùn)行期間動(dòng)態(tài)的加載一個(gè)外部的DLL集合,然后通過(guò)某種辦法找到這個(gè)DLL集合中的某個(gè)空間下的某個(gè)類的某個(gè)成員(通過(guò)反射可以訪問(wèn)該類所包含的所有成員,不論成員是公有還是私有),看看網(wǎng)上N人寫(xiě)的實(shí)例: namespace lab.CommonBasic.Common { class StringUtil { public double GetSum(double x, double y) { return x + y; } } } //這里要用LoadFrom,,只有在本工程里添加了該dll的引用后才可以使用Load Assembly objAss = Assembly.LoadFrom(@"D:\Test\HSMP.CommonBasic.dll"); //HSMP.CommonBasic.Common.StringUtil類的全路徑 Type t = objAss.GetType("HSMP.CommonBasic.Common.StringUtil"); //動(dòng)態(tài)生成類StringUtil的實(shí)例 object obj = System.Activator.CreateInstance(t); //參數(shù)信息,,GetSum需要兩個(gè)int參數(shù) System.Type[] paramTypes = new System.Type[2]; paramTypes[0] = System.Type.GetType("System.Int32"); paramTypes[1] = System.Type.GetType("System.Int32"); //找到對(duì)應(yīng)的方法 MethodInfo p = t.GetMethod("SayHello", paramTypes); // 也可以不給類型參數(shù),下面調(diào)用時(shí)給實(shí)參就可以 MethodInfo p = t.GetMethod("SayHello"); //參數(shù)值,如果所調(diào)用的方法沒(méi)有參數(shù),不用寫(xiě)這些 Object[] parameters = new Object[2]; parameters[0] = 3; parameters[1] = 4; //如果沒(méi)有參數(shù),,寫(xiě)null即可,。 object objRetval = p.Invoke(obj, parameters); 通過(guò)代碼可以看出反射其實(shí)很簡(jiǎn)單。就是動(dòng)態(tài)類型加載,。
以上我們用反射對(duì)靜態(tài)類型做加載,,但如果類是個(gè)范型類該怎么辦呢?其實(shí)方法大同小異,,只是獲取到類型時(shí)需要設(shè)置一下實(shí)際要使用的類型即可,,先看范型類定義: namespace lab.CommonBasic.Common { class StringUtil<T,U> { public string GetSum(T x, U y) { return x + " and " + y; } } } 再看反射操作: ... 前面代碼相同 //HSMP.CommonBasic.Common.StringUtil類的全路徑(范型類最后用 `2 標(biāo)示需要2個(gè)范型類型參數(shù)) Type t = objAss.GetType("HSMP.CommonBasic.Common.StringUtil`2"); // 這一步很重要,設(shè)置實(shí)際的范型類型 t = t.MakeGenericType(new Type[2] { typeof(string), typeof(string) }); //動(dòng)態(tài)生成類StringUtil的實(shí)例 object obj = System.Activator.CreateInstance(t); ... 后面代碼相同
還有一種情況,,如果類是常類,,但方法是范型方法改怎么辦?非常簡(jiǎn)單: ... 前面代碼相同 //HSMP.CommonBasic.Common.StringUtil類的全路徑(范型類最后用 `2 標(biāo)示需要2個(gè)范型類型參數(shù)) Type t = objAss.GetType("HSMP.CommonBasic.Common.StringUtil`2"); // 這一步要去掉,,因?yàn)轭惒皇欠盒皖愃圆荒芙o類設(shè)置范型類型 //t = t.MakeGenericType(new Type[2] { typeof(string), typeof(string) }); ... 中間代碼相同 // 區(qū)別在這里,把類級(jí)別的范型類型設(shè)置放到方法級(jí)別就可以了,。 MethodInfo p = t.GetMethod("SayHello"); MethodInfo p = p.MakeGenericMethod(new Type[2] { typeof(string), typeof(string) }); ... 后面代碼相同 class ChangeValue { // 這是私有字段 private string myValue; // 一般只有通過(guò)這樣的公共屬性外面才可能訪問(wèn)私有字段 public ChangeValue(string str) { myValue = str; } public void WriteLine() { Console.WriteLine("MyValue is: " + myValue); } } class Test { public static void Main(string[] args) { // 正常訪問(wèn) ChangeValue cv = new ChangeValue("old value"); cv.WriteLine(); //反射的方法直接訪問(wèn)私有字段 Type t = cv.GetType(); //得到私有字段對(duì)象并賦值 FieldInfo field = t.GetField("myValue", BindingFlags.NonPublic | BindingFlags.Instance); field.SetValue(cv, "new value"); //輸出的是新值 "new value" cv.WriteLine(); } }
|
|
來(lái)自: Jcstone > 《C#開(kāi)發(fā)》