反射,System.Type类
http://m.blog.csdn.net/blog/woddle/40623333
兩個現實中的例子:
1、B超:大家體檢的時候大概都做過B超吧,B超可以透過肚皮探測到你內臟的生理情況。這是如何做到的呢?B超是B型超聲波,它可以透過肚皮通過向你體內發射B型超聲波,當超聲波遇到內臟壁的時候就會產生一定的“回音”反射,然后把“回音”進行處理就可以顯示出內臟的情況了(我不是醫生也不是聲學專家,不知說得是否準確^_^)。
2、地球內部結構:地球的內部結構大體可以分為三層:地殼、地幔和地核。地殼是固體,地核是液體,地幔則是半液半固的結構(中學地理的內容,大家還記得吧?)。如何在地球表面不用深入地球內部就知道其內部的構造呢?對,向地球發射“地震波”,“地震波”分兩種一種是“橫波”,另一種是“縱波”。“橫波”只能穿透固體,而“縱波”既可穿透固體又可以穿透液體。通過在地面對縱波和橫波的反回情況,我們就可以大體斷定地球內部的構造了。
大家注意到這兩個例子的共同特點,就是從一個對象的外部去了解對象內部的構造,而且都是利用了波的反射功能。在.NET中的反射也可以實現從對象的外部來了解對象(或程序集)內部結構的功能,哪怕你不知道這個對象(或程序集)是個什么東西,另外.NET中的反射還可以運態創建出對象并執行它其中的方法。
反射是.NET中的重要機制,通過反射,可以在運行時獲得程序或程序集中每一個類型(包括類、結構、委托、接口和枚舉等)的成員和成員的信息。有了反射,即可對每一個類型了如指掌。另外我還可以直接創建對象,即使這個對象的類型在編譯時還不知道。?
????
反射的用途:
??? (1)使用Assembly定義和加載程序集,加載在程序集清單中列出模塊,以及從此程序集中查找類型并創建該類型的實例。?
??? (2)使用Module了解包含模塊的程序集以及模塊中的類等,還可以獲取在模塊上定義的所有全局方法或其他特定的非全局方法。?
??? (3)使用ConstructorInfo了解構造函數的名稱、參數、訪問修飾符(如pulic 或private)和實現詳細信息(如abstract或virtual)等。?
??? (4)使用MethodInfo了解方法的名稱、返回類型、參數、訪問修飾符(如pulic 或private)和實現詳細信息(如abstract或virtual)等。
??? (5)使用FiedInfo了解字段的名稱、訪問修飾符(如public或private)和實現詳細信息(如static)等,并獲取或設置字段值。
??? (6)使用EventInfo了解事件的名稱、事件處理程序數據類型、自定義屬性、聲明類型和反射類型等,添加或移除事件處理程序。?
??? (7)使用PropertyInfo了解屬性的名稱、數據類型、聲明類型、反射類型和只讀或可寫狀態等,獲取或設置屬性值。?
??? (8)使用ParameterInfo了解參數的名稱、數據類型、是輸入參數還是輸出參數,以及參數在方法簽名中的位置等。
反射用到的命名空間:
??? System.Reflection
??? System.Type
??? System.Reflection.Assembly
????
反射用到的主要類:
??? System.Type 類--通過這個類可以訪問任何給定數據類型的信息。
??? System.Reflection.Assembly類--它可以用于訪問給定程序集的信息,或者把這個程序集加載到程序中。
????
System.Type類:
??? System.Type 類對于反射起著核心的作用。但它是一個抽象的基類,Type有與每種數據類型對應的派生類,我們使用這個派生類的對象的方法、字段、屬性來查找有關該類型的所有信息。
??? 獲取給定類型的Type引用有3種常用方式:
????●使用 C# typeof 運算符。
??????? Type t = typeof(string);
??? ●使用對象GetType()方法。
??????? string s = "grayworm";
??????? Type t = s.GetType();?
??? ●還可以調用Type類的靜態方法GetType()。
??????? Type t = Type.GetType("System.String");
???????
??? 上面這三類代碼都是獲取string類型的Type,在取出string類型的Type引用t后,我們就可以通過t來探測string類型的結構了。?
????????????string n = "grayworm";
??????????? Type t = n.GetType();
??????????? foreach (MemberInfo mi in t.GetMembers())
??????????? {
??????????????? Console.WriteLine("{0}/t{1}",mi.MemberType,mi.Name);
??????????? }
????
????Type類的屬性:
??????? Name 數據類型名
??????? FullName 數據類型的完全限定名(包括命名空間名)
??????? Namespace 定義數據類型的命名空間名
??????? IsAbstract 指示該類型是否是抽象類型
??????? IsArray?? 指示該類型是否是數組
??????? IsClass?? 指示該類型是否是類
??????? IsEnum?? 指示該類型是否是枚舉
??????? IsInterface??? 指示該類型是否是接口
??????? IsPublic 指示該類型是否是公有的
??????? IsSealed 指示該類型是否是密封類
??????? IsValueType 指示該類型是否是值類型
????Type類的方法:
??????? GetConstructor(), GetConstructors():返回ConstructorInfo類型,用于取得該類的構造函數的信息
??????? GetEvent(), GetEvents():返回EventInfo類型,用于取得該類的事件的信息
??????? GetField(), GetFields():返回FieldInfo類型,用于取得該類的字段(成員變量)的信息
??????? GetInterface(), GetInterfaces():返回InterfaceInfo類型,用于取得該類實現的接口的信息
??????? GetMember(), GetMembers():返回MemberInfo類型,用于取得該類的所有成員的信息
??????? GetMethod(), GetMethods():返回MethodInfo類型,用于取得該類的方法的信息
??????? GetProperty(), GetProperties():返回PropertyInfo類型,用于取得該類的屬性的信息
??? 可以調用這些成員,其方式是調用Type的InvokeMember()方法,或者調用MethodInfo, PropertyInfo和其他類的Invoke()方法。?
????
????查看類中的構造方法:
????????NewClassw nc = new NewClassw();
????????Type t = nc.GetType();
??????? ConstructorInfo[] ci = t.GetConstructors();??? //獲取類的所有構造函數
??????? foreach (ConstructorInfo c in ci) //遍歷每一個構造函數
??????? {
????????????ParameterInfo[] ps = c.GetParameters();??? //取出每個構造函數的所有參數
??????????? foreach (ParameterInfo pi in ps)?? //遍歷并打印所該構造函數的所有參數
??????????? {
??????????????? Console.Write(pi.ParameterType.ToString()+" "+pi.Name+",");
??????????? }
??????????? Console.WriteLine();
??????? }
????
????用構造函數動態生成對象:
????????Type t = typeof(NewClassw);
????????Type[] pt = new Type[2];
??????? pt[0] = typeof(string);
??????? pt[1] = typeof(string);
??????? //根據參數類型獲取構造函數?
????????ConstructorInfo ci = t.GetConstructor(pt);?
??????? //構造Object數組,作為構造函數的輸入參數?
????????object[] obj = new object[2]{"grayworm","hi.baidu.com/grayworm"};???
??????? //調用構造函數生成對象?
????????object o = ci.Invoke(obj);????
??????? //調用生成的對象的方法測試是否對象生成成功?
??????? //((NewClassw)o).show();????
????
????用Activator生成對象:
????????Type t = typeof(NewClassw);
??????? //構造函數的參數?
??????? object[] obj = new object[2] { "grayworm", "hi.baidu.com/grayworm" };???
??????? //用Activator的CreateInstance靜態方法,生成新對象?
????????object o = Activator.CreateInstance(t,"grayworm","hi.baidu.com/grayworm");?
??????? //((NewClassw)o).show();
????查看類中的屬性:
????????NewClassw nc = new NewClassw();
??????? Type t = nc.GetType();
????????PropertyInfo[] pis = t.GetProperties();
??????? foreach(PropertyInfo pi in pis)
??????? {
??????????? Console.WriteLine(pi.Name);
??????? }
????
????查看類中的public方法:
????????NewClassw nc = new NewClassw();
??????? Type t = nc.GetType();
????????MethodInfo[] mis = t.GetMethods();
??????? foreach (MethodInfo mi in mis)
??????? {
??????????? Console.WriteLine(mi.ReturnType+" "+mi.Name);
??????? }
????
????查看類中的public字段
????????NewClassw nc = new NewClassw();
??????? Type t = nc.GetType();
??????? FieldInfo[] fis = t.GetFields();
??????? foreach (FieldInfo fi in fis)
??????? {
??????????? Console.WriteLine(fi.Name);
??????? }?(http://hi.baidu.com/grayworm)
???????
????用反射生成對象,并調用屬性、方法和字段進行操作?
????????NewClassw nc = new NewClassw();
??????? Type t = nc.GetType();
??????? object obj = Activator.CreateInstance(t);
??????? //取得ID字段?
??????? FieldInfo fi = t.GetField("ID");
??????? //給ID字段賦值?
??????? fi.SetValue(obj, "k001");
??????? //取得MyName屬性?
??????? PropertyInfo pi1 = t.GetProperty("MyName");
??????? //給MyName屬性賦值?
??????? pi1.SetValue(obj, "grayworm", null);
??????? PropertyInfo pi2 = t.GetProperty("MyInfo");
??????? pi2.SetValue(obj, "hi.baidu.com/grayworm", null);
??????? //取得show方法?
??????? MethodInfo mi = t.GetMethod("show");
??????? //調用show方法?
??????? mi.Invoke(obj, null);????
System.Reflection.Assembly類?
???? Assembly類可以獲得程序集的信息,也可以動態的加載程序集,以及在程序集中查找類型信息,并創建該類型的實例。
??? 使用Assembly類可以降低程序集之間的耦合,有利于軟件結構的合理化。
????
????通過程序集名稱返回Assembly對象
??????? Assembly ass = Assembly.Load("ClassLibrary831");
??? 通過DLL文件名稱返回Assembly對象
??????? Assembly ass = Assembly.LoadFrom("ClassLibrary831.dll");
??? 通過Assembly獲取程序集中類?
??????? Type t = ass.GetType("ClassLibrary831.NewClass");?? //參數必須是類的全名
??? 通過Assembly獲取程序集中所有的類
??????? Type[] t = ass.GetTypes();
???????
??? //通過程序集的名稱反射
????Assembly ass = Assembly.Load("ClassLibrary831");
??? Type t = ass.GetType("ClassLibrary831.NewClass");
??? object o = Activator.CreateInstance(t, "grayworm", "http://hi.baidu.com/grayworm");
??? MethodInfo mi = t.GetMethod("show");
??? mi.Invoke(o, null);
???//通過DLL文件全名反射其中的所有類型
????Assembly assembly = Assembly.LoadFrom("xxx.dll的路徑");
??? Type[] aa = a.GetTypes();
??? foreach(Type t in aa)
??? {
??????? if(t.FullName == "a.b.c")
??????? {
??????????? object o = Activator.CreateInstance(t);
??????? }
??? }?
轉載于:https://www.cnblogs.com/salansun/p/4937578.html
總結
以上是生活随笔為你收集整理的反射,System.Type类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iptables 性能 测试
- 下一篇: python代码文件生成exe文件