深入浅出 .NET C# 反射技术
反射这个词听起来就很牛逼是吧?
嗯的确,反射是比较高级的特性,只有语言基础很扎实的Dev们才应该使用它。
搞点反射,可以提高程序的灵活性、可扩展性、耦合度。
反射这东西,是为了动态地运行时加载,相比于静态代码。编译的时候就是板上钉钉了。
就是说,如果你的程序需要在运行时搞一些晚绑定,动态加载或检查对象之类的操作时,那么反射欢迎你。
说到这,也许有人立刻就去找反射相关的文档和教程,想赶紧把反射技术实践到程序上。
给爷爪巴
使用反射是要分场合的
反射基本上是一种解释操作,用于字段啊方法啊接入时要远慢于直接撸代码。
因此反射机制主要应用在对灵活性和拓展性要求很高的东西上,普通程序不建议使用。
还有一件事,如果你程序全用的反射。一时反射一时爽,后期维护秒跑路。
程序员最烦的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 = ;
- }
- //派生类
- class DerivedClass : BaseClass
- {
- public int DerivedField = ;
- }
- 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();
- 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的时候才能,把基类的也输出出来。
深入浅出 .NET C# 反射技术的更多相关文章
- [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程
[.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程 本节导读:本节主要介绍什么是.NET反射特性,.NET反射能为我们做些什么,最后介绍几种常用的 ...
- 程序集与反射技术(C#)
首先我们来看程序集,程序集是代码进行编译是的一个逻辑单元,把相关的代码和类型进行组合,然后生成PE文件(例如可执行文件.exe和类库文件.dll).由于程序集在编译后并不一定会生成单个文件,而可能会生 ...
- C#反射技术概念作用和要点
反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的 ...
- 【Android测试】【第十七节】Instrumentation——App任你摆布(反射技术的引入)
◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/5569844.html 前言 学习了上节之后,大家是否已经 ...
- 黑马程序员:Java编程_反射技术
=========== ASP.Net+Android+IOS开发..Net培训.期待与您交流!=========== Java类用于描述一类事物的共性,该类事物有什么属性,没有什么属性,至于这个属性 ...
- java 反射技术
什么是反射?反射就是将字节码中的各种成分映射到相应的java类中来,java反射技术自JDK1.1以来就出现了,目前大多数流行的框架都采用了这种技术,可见其重要性,这篇文章将详细介绍我对java反射技 ...
- C#反射技术的简单操作(读取和设置类的属性)
public class A { public int Property1 { get; set; } } static void Main(){ A aa = new A(); Type type ...
- Android中Java反射技术的使用示例
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Metho ...
- 【转】.Net中通过反射技术的应用----插件程序的开发入门
转自:http://www.cnblogs.com/winloa/archive/2012/03/25/2416355.html .Net中通过反射技术的应用----插件程序的开发入门 再开始之前,先 ...
随机推荐
- 简单看看LockSupport和AQS
这次我们可以看看并发中锁的原理,大概会说到AQS,ReentrantLock,ReentrantReadWriteLock以及JDK8中新增的StampedLock,这些都是在java并发中很重要的东 ...
- influxdb+Grafana+jmeter监控搭建
安装InfluxDB InfluxDB的简介 InfluxDB 是用Go语言编写的一个开源分布式时序.事件和指标数据库,无需外部依赖. 类似的数据库有Elasticsearch.Graphite等.. ...
- [校内训练20_01_22]ABC
1.给出序列A,求序列B,使得bi|ai,lcm(b1,b2,...,bn)=lcm(a1,a2,...,an)且字典序最小. 可以发现,对于某个质数p,它有一个最大的次数k,将pk放在尽可能靠后且能 ...
- Arrays.asList()用法梳理
Arrays.asList()用法梳理 asList概述 Arrays是java容器相关操作的工具类,asList方法将Array转换为list,是Array和List之间的桥梁. asList本质 ...
- RabbitMq 深入了解
积少成多 ---- 仅以此致敬和我一样在慢慢前进的人儿 问题一:什么是RabbitMq 下面就是些个人的感受, rabbitmq 就是一个遵循AMQP协议(这个是啥不清楚) 的消息队列的实现,用于服 ...
- spring源码系列博文总索引
一 目录 准备 1 使用Gradle构建spring5源码的一些坑和步骤 IOC模块 1spring IOC接口设计分析 2 spring IOC容器实现类分析 3 spring IOC特定场景源码步 ...
- js的new操作符深度解析
引言 我们都知道new操作符在js中一般是用来创建一个构造函数的实例,它在创建实例具体做了什么,MDN文档是这么说的: 我一开始看到,完全没有任何的头绪和理解,到底什么意思,后面通过上网查阅了大量的资 ...
- k8s基本命令
kubernetes 常用命令 通过yaml文件创建: kubectl create -f xxx.yaml (不建议使用,无法更新,必须先delete) kubectl apply -f xxx.y ...
- Dubbo Cluster集群那点你不知道的事。
这是why技术的第33篇原创文章 本周是在家办公的一周,上面的图就是我在家的工位. 工欲善其事,必先利其器.在家办公,我是认真的. 在家里开发的时候有需求是这样的:一个如果接口调用失败,需要自动进行重 ...
- 将你的Archlinux打造成路由器
弄了一块J2900双千兆网口的工控板回来(奇怪的型号)当软路由用,无奈我又想各种皮,还想装桌面环境配VNC,而且我还对虚拟机不感冒(况且这U还不支持直通),只得放弃所有路由器系统.作为一名Arch铁粉 ...