反射的概念
审查元数据并收集关于它的类型信息的能力。元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等。System.reflection命名空间包含的一些个类,提供了方法,允许你反射(解析)这些元数据表的代码 。
为什么要反射
因为需要在运行时取得一些编译期不存在的类型的信息,创建实例,或者调用方法。
反射的性能
- 反射造成编译时无法保证类型的安全性。由于反射严重依赖字符串,所以会丧失编译时的类型安全性。
- 反射速度慢。使用反射时,需要用字符串名称在运行时查找。使用反射调用成员方法时,必须将实参打包成数组,在内部,反射必须将这些实参解包到线程栈上。
可执行应用程序的结构
(1) AppDomain(Application Domain,简称App Domain):应用程序域,可以将其理解为一组程序集的逻辑容器 。
(2) Assembly:程序集类 。
(3) Module:模块类 。
(4) Type:使用反射得到类型信息的最核心的类 。
程序集包含模块,而模块包含类型,类型又包含成员,反射则提供了封装程序集、模块和类型的对象。我们可以使用反射动态地创建类型的实例,将类型绑定到现有对象或从现有对象中获取类型,然后调用类型的方法或访问其字段和属性。
AppDomain
应用程序域或AppDomain是.NET Framework最强大的功能之一。 AppDomain可被视为轻量级的进程。AppDomain是一个.NET概念,进程是操作系统概念,两者有许多共同的特征。一个进程可以包含多个AppDomain,每个AppDomain都在该进程中提供一个隔离单位。不同AppDomain之间的代码是相互隔离的,可以理解为是一个代码和数据的隔离空间,不允许其他AppDomain的非法访问。
为什么有了进程还需要AppDomian呢?进程的创建和维护更昂贵。AppDomain也提供很多进程的特性,但是它允许多个assemblies在一个AppDomain中。一个.NET管理的应用进程中,至少有一个AppDomain。
Assembly 程序集
简单来说创建控制台应用程序或Windows窗体应用程序或类库或.NET中的其他类型的应用程序时,您正在创建一个Assembly。Assembly 可以是一个 .exe 或者 .dll。当你加载一个dll的时候,你正在loading一个Assembly。
Module (System.Reflection.Module)
一个Assembly可以被多个Module组成,并且被拆分到不同的文件里。起因是因为.Net团队认为,用户能够通过网络将程序集下载到其本地计算机以进行执行是很重要的。那么就可以先main Module,再在有需要时下载其他的module。但是这个已经基本变成时代的眼泪了,现在大部分的Assembly里只包含一个main Module。
Type (System.Type)
System.Type主要用在反射里取得一个类型的相关信息。