一:什么是反射
C#編寫的程序會編譯成一個程序集(.DLL或.exe),其中會包含元數(shù)據(jù)、編譯代碼和資源,通過反射可以獲取到程序集中的信息
通俗來講,反射就是我們在只知道一個對象的外部而不了解內(nèi)部結(jié)構(gòu)的情況下,可以知道這個對象的內(nèi)部實現(xiàn)
二:反射的優(yōu)缺點
首先在編譯中分為動態(tài)編譯和靜態(tài)編譯,靜態(tài)編譯是在編譯中確定類型,綁定對象,而動態(tài)編譯是在運行中確定類型,綁定對象
反射的優(yōu)點就是可以動態(tài)創(chuàng)建對象、綁定對象,提高了程序的靈活性和擴(kuò)展性,但反射是一種解釋操作,在性能上不如靜態(tài)編譯快
三:通過Type類獲取程序集、模塊、類的相關(guān)信息
——Type類是一個抽象類,因此不能用他去實例化對象
——object類中定義了一個GetType方法,因此所有類都可以使用GetType()獲取到某一個對象所屬類的Type對象
——通過Type對象可以獲取到類中字段、屬性、方法、構(gòu)造函數(shù)等信息
using System; class MainClass { public static void Main(string[] args) { //1.通過對象獲取到這個對象所屬類的Type對象 TestClass c = new TestClass(); Type t = c.GetType(); //2.通過Type類中的靜態(tài)方法GetType獲取到類的Type對象 //Type t = Type.GetType("TestClass"); //3.通過typeof關(guān)鍵字獲取到類的Type對象 //Type t = typeof(TestClass); Console.WriteLine(t.Name);//獲取類名(不帶命名空間) Console.WriteLine(t.FullName);//獲取類名(帶命名空間) Console.WriteLine(t.Assembly);//獲取程序集 Console.WriteLine(t.BaseType);//獲取基類類型 Console.WriteLine("----------獲取類中字段"); var fields = t.GetFields(); foreach (var temp in fields) { Console.WriteLine(temp.Name); } Console.WriteLine("----------獲取類中屬性"); var properties = t.GetProperties(); foreach (var temp in properties) { Console.WriteLine(temp.Name); } Console.WriteLine("----------獲取類中方法"); var methods = t.GetMethods(); foreach (var temp in methods) { Console.WriteLine(temp.Name); } Console.WriteLine("----------獲取類中成員"); var members = t.GetMembers(); foreach (var temp in members) { Console.WriteLine(temp.Name); } Console.WriteLine("----------獲取類中嵌套類"); var nesteds = t.GetNestedTypes(); foreach (var temp in nesteds) { Console.WriteLine(temp.Name); } Console.WriteLine("----------獲取類中構(gòu)造函數(shù)"); var constructors = t.GetConstructors(); foreach (var temp in constructors) { Console.WriteLine(temp.Name); } } } public class TestClass { public string str; public int num { get; set; } public void Fun() { } public class TestNestedClass { } }
得到一個Type類型對象有三種方法:object.GetType()、Type.GetType()、typeof()
使用object.GetType()必須先創(chuàng)建一個實例,而后兩種不需要創(chuàng)建實例,但使用typeof運算符仍然需要知道類型的編譯時信息,Type.GetType()靜態(tài)方法不需要知道類型的編譯時信息,所以是首選方法
四:創(chuàng)建實例:性能上要比new差
——通過Activator創(chuàng)建實例
using System; class MainClass { public static void Main(string[] args) { object c = Activator.CreateInstance(typeof(TestClass), "hello world"); Console.WriteLine(((TestClass)c).str); } } public class TestClass { public string str; public TestClass(string str) { this.str = str; } }
?
?
——通過構(gòu)造函數(shù)創(chuàng)建實例
using System; class MainClass { public static void Main(string[] args) { Type t = typeof(TestClass); Type[] paramTypes = new Type[1] { typeof(string) }; var info = t.GetConstructor(paramTypes); object[] param = new object[1] { "hello world" }; var o = info.Invoke(param); Console.WriteLine(((TestClass)o).str); } } public class TestClass { public string str; public TestClass(string str) { this.str = str; } }
五:反射賦值
using System; using System.Reflection; class MainClass { public static void Main(string[] args) { TestClass cc = new TestClass(); Type t = cc.GetType(); FieldInfo info = t.GetField("str"); info.SetValue(cc, "hello world"); Console.WriteLine(info.GetValue(cc)); } } public class TestClass { public string str; }
?
本文摘自 :https://blog.51cto.com/u