反射無處不在,我們天天在使用。VS的智能提示,就是通過反射獲取到類的屬性、方法等。還有反編譯工具也是通過反射實現。
反射就是動態獲取程序集的元數據(提供程序集的類型信息)的功能。
反射就是動態獲取程序集中的元數據來操作類型的
Type類實現反射的一個重要的類,通過它我們可以獲取類中的所有信息,包括方法、屬性等。可以動態調用累的屬性、方法。Type是對類的描述。
反射就是直接通過 .dll 來創建對象,調用成員。
通過類型元數據來獲取對象的一些相關信息,并且還可以實例化對象調用方法等,這個就叫做 ”反射” 。
反射讓創建對象的方式發生了改變。
編譯器的智能提示就是反射的一個應用。
Type類的使用
通過類獲得Type: Type t = typeof( person )
通過對象獲得類的Type: Type t = p.GetType( )
動態加載程序集
string path = @"F:/MyCSharp/練習/練習/ClassLibrary1/bin/Debug/ClassLibrary1.dll";//加載程序集Assembly asm = Assembly.LoadFile(path);
調用 Assembly 的 GetExportedTypers 方法可以得到 Assembly 中定義的所有 public 類型
Type[] types = asm.GetExportedTypes();//獲得程序集中定義的所有 public 類型 返回值是一個類型數組
調用 Assembly 的 GetTpye( name ) 方法可以得到 Assembly 中定義的全名為 name 的類型信息
//獲取指定的某個類型,必須寫該類型的"全名"(完全限定名稱:ClassLibrary1.Person)Type typePerson = asm.GetType("ClassLibrary1.Person");GetConstructor ( 參數列表 ) ; //這是一個找到帶參數的構造函數
Activator.CreateInstance( Type t ) 會動態調用類的無參構造函數創建一個對象,返回值就是創建的對象,如果類沒有無參構造函數機會報錯
string path = @"F:/MyCSharp/練習/練習/ClassLibrary1/bin/Debug/ClassLibrary1.dll";//加載程序集Assembly asm = Assembly.LoadFile(path);//獲得某個類型的TypeType typeStudent = asm.GetType("ClassLibrary1.Student");Type typePerson = asm.GetType("ClassLibrary1.Person");Type typeIFlyable = asm.GetType("ClassLibrary1.IFlyable");//使用CreateInstance(Type t) 創建對象object student = Activator.CreateInstance(typeStudent);//調用的是無參的構造函數object person = Activator.CreateInstance(typePerson);//調用的是無參的構造函數Type類的方法:在編寫調用插件的程序時,需要做一系列驗證。
bool IsAssignableFrom( Type c ); 判斷當前的類型的變量是不是可以接受 c 類型變量的賦值。
 1 //1、IsAssignableFrom(),就是驗證是否可以將某個類型的對象賦值給另外一個類型的變量 2 string path = @"F:/MyCSharp/練習/練習/ClassLibrary1/bin/Debug/ClassLibrary1.dll"; 3 //加載程序集 4 Assembly asm = Assembly.LoadFile(path); 5 //獲得某個類型的Type 6 Type typeStudent = asm.GetType("ClassLibrary1.Student"); 7 Type typePerson = asm.GetType("ClassLibrary1.Person"); 8 Type typeIFlyable = asm.GetType("ClassLibrary1.IFlyable"); 9 //返回true 表示可以將 typeStudnet 的對象賦值給 typePerson 類型10 Console.WriteLine(typePerson.IsAssignableFrom(typeStudent));11 //是否可以把 typeStudent 對象賦值給 typeIFlyable 類型變量12 Console.WriteLine(typeIFlyable.IsAssignableFrom(typePerson));13 //是否可以把 typeStudent 對象賦值給 typeIFlyable 類型變量14 Console.WriteLine(typeIFlyable.IsAssignableFrom(typeStudent));15 Console.ReadKey();bool IsInstanceOfType( object o ); 判斷對象o是否是當前類的實例(當前類可以是o的類、父類、接口)
 1 string path = @"F:/MyCSharp/練習/練習/ClassLibrary1/bin/Debug/ClassLibrary1.dll"; 2 //加載程序集 3 Assembly asm = Assembly.LoadFile(path); 4 //獲得某個類型的Type 5 Type typeStudent = asm.GetType("ClassLibrary1.Student"); 6 Type typePerson = asm.GetType("ClassLibrary1.Person"); 7 Type typeIFlyable = asm.GetType("ClassLibrary1.IFlyable"); 8 object student = Activator.CreateInstance(typeStudent); 9 object person = Activator.CreateInstance(typePerson);10 //person 這個對象是否是當前指定的 typePerson 的對象11 Console.WriteLine(typePerson.IsInstanceOfType(person));//true12 //student 這個對象是否是當前指定的 typePerson 的對象13 Console.WriteLine(typePerson.IsInstanceOfType(student));//true14 //person 這個對象是否是當前指定的 typeStudent 的對象15 Console.WriteLine(typeStudent.IsInstanceOfType(person));//false16 //student 這個對象是否是當前指定的 typeStudent 的對象17 Console.WriteLine(typeStudent.IsInstanceOfType(student));//true18 //person 這個對象是否是當前指定的 typeIFlyable 的對象19 Console.WriteLine(typeIFlyable.IsInstanceOfType(person));//false20 //student 這個對象是否是當前指定的 typeIFlyable 的對象21 Console.WriteLine(typeIFlyable.IsInstanceOfType(student));//true22 Console.ReadKey();bool IsSubclassOf( Type c ); 判斷當前類是否是類c的子類。(與接口無關)
 1 //3、IsSubclassOf(Type c)    判斷當前類是否是類 c 的子類,只是類,沒有接口的事 2 string path = @"F:/MyCSharp/練習/練習/ClassLibrary1/bin/Debug/ClassLibrary1.dll"; 3 //加載程序集 4 Assembly asm = Assembly.LoadFile(path); 5 //獲得某個類型的Type 6 Type typeStudent = asm.GetType("ClassLibrary1.Student"); 7 Type typePerson = asm.GetType("ClassLibrary1.Person"); 8 Type typeIFlyable = asm.GetType("ClassLibrary1.IFlyable"); 9 //創建指定類型的對象10 object student = Activator.CreateInstance(typeStudent);11 object person = Activator.CreateInstance(typePerson);12 //判斷 typeStudent 是否是 typePerson 的子類13 Console.WriteLine(typeStudent.IsSubclassOf(typePerson));//true14 //判斷 typePerson 是否是 typeIFlyable 的子類15 Console.WriteLine(typePerson.IsSubclassOf(typeIFlyable));//false16 //判斷 typeStudent 是否是 typeIFlyable 的子類17 Console.WriteLine(typeStudent.IsSubclassOf(typeIFlyable));//false18 Console.ReadKey();IsAbstract 判斷是否為抽象的,包含接口
 1 //4、IsAbstract  判斷是否為抽象的,含接口 2 string path = @"F:/MyCSharp/練習/練習/ClassLibrary1/bin/Debug/ClassLibrary1.dll"; 3  4 //加載程序集 5 Assembly asm = Assembly.LoadFile(path); 6  7 //獲得某個類型的Type 8 Type typeStudent = asm.GetType("ClassLibrary1.Student"); 9 Type typePerson = asm.GetType("ClassLibrary1.Person");10 Type typeIFlyable = asm.GetType("ClassLibrary1.IFlyable");11 Type typeMyclass1 = asm.GetType("ClassLibrary1.MyClass1");12 Type typeMyclass2 = asm.GetType("ClassLibrary1.MyClass2");13 14 //創建指定類型的對象15 object student = Activator.CreateInstance(typeStudent);16 object person = Activator.CreateInstance(typePerson);17 18 //判斷是否為抽象的,含接口19 Console.WriteLine(typeStudent.IsAbstract);//false20 Console.WriteLine(typePerson.IsAbstract);//false21 Console.WriteLine(typeIFlyable.IsAbstract);//true22 Console.WriteLine(typeMyclass1.IsAbstract);//true23 Console.WriteLine(typeMyclass2.IsAbstract);//true24 25 Console.ReadKey();MemberInfo類 抽象類,有很多子類,下面所有類都繼承自 MemberInfo 類:
PRopertyInfo 獲取屬性
1 //所有的屬性2 PropertyInfo[] properties = typePerson.GetProperties();3 //通過循環輸出每一個屬性的名稱4 for (int i = 0; i < properties.Length; i++)5 {6     //循環輸出7     Console.WriteLine(properties[i].Name);8 }9 Console.ReadKey(); 主要成員:
CanRead、CanWrite、PropertyType屬性類型;
SetValue、GetValue:讀取值、設置值第一個參數是實例對象,因為set、get要針對具體實例,最后一個參數 null 。pInfo.SetValue( p1, 30, null );
MethodInfo 獲取方法
1 //獲取 Person 類中的所有的方法2 MethodInfo[] methods = typePerson.GetMethods();3 //遍歷獲取到的所有方法的數組4 for (int i = 0; i < methods.Length; i++)5 {6     //輸出所有方法的方法名7     Console.WriteLine(methods[i].Name);8 }9 Console.ReadKey(); 獲得某一個指定的方法1 //獲得Person類名字為SayHi的方法,并且是沒有任何參數的方法2 MethodInfo method = typePerson.GetMethod("SayHi")調用這個方法
 1 MethodInfo method = typePerson.GetMethod("SayHi"); 2 //判斷獲得的方法是否為空 3 if (method != null) 4 { 5     //因為SayHi()方法是一個實例方法,不是靜態方法,所以調用SayHi()方法的時候,必須在某個對象上調用,所以method.Invoke() 需要傳遞一個具體的Person對象進去 6     object obj = Activator.CreateInstance(typePerson);//創建一個Person對象 7         //調用Invoke() 方法要把person創建的對象傳進來 8     method.Invoke(obj, null);//調用SayHi()方法,如果這個方法沒有參數第二個參數為null 9 }10 else11 {12     Console.WriteLine("找不懂啊你要調用的方法");13 }14 Console.ReadKey(); //獲得方法名為 SayHi 的重載方法(第二個參數為對應類型的參數:typeof(參數相應類型))MethodInfo method = typePerson.GetMethod("SayHi", new Type[] { typeof(string), typeof(string) });if (method != null){    //因為SayHi()方法是一個實例方法,不是靜態方法,所以調用SayHi()方法的時候,必須在某
新聞熱點
疑難解答