反射这个词听起来就很牛逼是吧?程序员
嗯的确,反射是比较高级的特性,只有语言基础很扎实的Dev们才应该使用它。数组
搞点反射,能够提升程序的灵活性、可扩展性、耦合度。spa
反射这东西,是为了动态地运行时加载,相比于静态代码。编译的时候就是板上钉钉了。code
就是说,若是你的程序须要在运行时搞一些晚绑定,动态加载或检查对象之类的操做时,那么反射欢迎你。对象
说到这,也许有人马上就去找反射相关的文档和教程,想赶忙把反射技术实践到程序上。blog
给爷爪巴继承
使用反射是要分场合的教程
反射基本上是一种解释操做,用于字段啊方法啊接入时要远慢于直接撸代码。ci
所以反射机制主要应用在对灵活性和拓展性要求很高的东西上,普通程序不建议使用。element
还有一件事,若是你程序全用的反射。一时反射一时爽,后期维护秒跑路。
程序员最烦的2件事是什么,维护没有注释的代码和写注释。但当程序员看到代码有一大堆的反射并且没写注释的时候,他们会直接/kill @p就完事了。
由于 反 射 绕 过 了 源 代 码 的 技 术 ,反射代码贼JB复杂,相比普通的来讲
BCL声明了一个Type类型(它是抽象类),用来包含类型的特性。使用这个类的对象能让咱们获取程序使用的类型的信息。
因为Type是抽象类,因此它不能被实例化。而是在运行时,CLR建立从Type(RuntimeType)派生的类型的实例。当咱们要访问这些实例的时候,CLR不会返回派生类的引用而是返回Type基类的引用。
关于Type有以下重要的点:
①对于程序每个须要用到的类型,CLR会穿件一个包含这个类型信息的Type类型的对象(真实的是上面说的派生的类型的实例)。
②程序中用到的每个类型都会关联到独立的Type类的对两个象。
③不管建立的类型有多少个实例,只有一个Type对象会关联到全部这些实例。就像下面的图表示的同样。建立了一个OtherClass的实例oc、以及两个MyClass的实例mc1和mc2,可是在堆上都只会有一个Type对象来的对应他们,以下面的图示:
如今咱们知道,object类型包含了一个GetType方法,它能够用来返回事例的Type对象引用。因为全部的类都是继承自object类型,因此全部的类均可以调用GetType来得到Type类型对象的引用。
因此下面的代码,在遍历派生类的Field的时候才能,把基类的也输出出来。
//鸡肋 class BaseClass { public int BaseField = 0; } //派生类 class DerivedClass : BaseClass { public int DerivedField = 0; } class Program { static void Main(string[] args) { var bc = new BaseClass(); var dc = new DerivedClass(); BaseClass[] bca = new BaseClass[] { bc, dc }; foreach(var v in bca) { //获取类型 Type t = v.GetType(); Console.WriteLine("Object Type: {0}", t.Name); //获取类中的字段 FieldInfo[] fi = t.GetFields(); foreach (var f in fi) Console.WriteLine(" Field:{0}", f.Name); Console.WriteLine(); } Console.WriteLine("End!"); Console.ReadKey(); } }
方法二:经过typeof()方法来获取一个类型的Type对象引用。例以下面的代码:
1
|
Type t =
typeof
(DerivedClass);
|
//经过程序集获取类型 var baseType = Assembly.GetExecutingAssembly().GetType("TestDemo.BaseClass"); var derivedType = Assembly.GetExecutingAssembly().GetType("TestDemo.DerivedClass");
很好,来个经常使用的骚操做。结合GetType和typeof操做,能够作不少事情....
static void Main(string[] args) { var intArray = typeof(int).MakeArrayType(); var int3Array = typeof(int).MakeArrayType(3); Console.WriteLine($"是不是int 数组 intArray == typeof(int[]) :{intArray == typeof(int[]) }"); Console.WriteLine($"是不是int 3维数组 intArray3 == typeof(int[]) :{int3Array == typeof(int[]) }"); Console.WriteLine($"是不是int 3维数组 intArray3 == typeof(int[,,]):{int3Array == typeof(int[,,]) }"); //数组元素的类型 Type elementType = intArray.GetElementType(); Type elementType2 = int3Array.GetElementType(); Console.WriteLine($"{intArray}类型元素类型:{elementType }"); Console.WriteLine($"{int3Array}类型元素类型:{elementType2 }"); //获取数组的维数 var rank = int3Array.GetArrayRank(); Console.WriteLine($"{int3Array}类型维数:{rank }"); Console.ReadKey(); }
未完待续...
因此下面的代码,在遍历派生类的Field的时候才能,把基类的也输出出来。