反射机制(Reflection)通常会涉及到3中场景:

  • 运行时反射

    • 场景:可以检索已加载程序集、类型、对象、实例和方法调用的元数据(Metadata)。
    • .NET 支持情况:支持
  • 仅供静态分析的反射
    • 场景:可以检索程序集中定义的类型和对象的元数据,而不会产生其他副作用。
    • .NET 支持情况:有限的支持
  • 反射扩展性
    • 场景:在上述两种场景下扩展元数据。
    • .NET 支持情况:支持,但非常复杂

System.Type 是反射模型中的最主要的抽象和入口点。它被用于描述两种相关但却不同的概念:基本信息(reference)和定义(definition),并使两者之间可以互操作。这使得其并不满足关注点分离(Separation of Concerns)设计原则。

从概念上讲,reference 是某种事物的浅显表述,而 definition 提供更丰富的表述。例如 System.Reflection.Assembly 类代表了程序集的 definitions,而System.Reflection.AssemblyName 类则代表了程序集的 references 。前者暴露了丰富的功能,而后者仅是提供能够获取定义的数据。

.NET 4.5 中包含了一些对传统反射机制的变更。其中最重要的变化是,System.Type 类被分割至两个独立的类中:Type 和 TypeInfo。TypeInfo 实例包含 Type 的定义,而 Type 则只关心数据。

  • Type:提供对象结构的浅视图,主要用于持有数据。(reference
  • TypeInfo:提供对象结构的完整视图,包含对象与父类及子类的关系。(definition

BCL中的变化

  • Assembly.DefinedTypes 属性返回 TypeInfo。

    • 该 API 负责获取程序集内定义的所有类型。
  • Type.BaseType 属性返回 Type。
    • 该 API 尽返回父类型的表述,而不是 definition
    • 父类型有可能被定义在另一个程序集内,这就需要一次程序集加载。
  • Object.GetType 方法返回 Type。
    • 该 API 返回 Type,因为你仅需要类型的表述。
    • 该类型有可能被定义在另一个程序集内,这就需要一次程序集加载。
  • C# 关键字 typeof 返回 Type。
    • 与 Object.GetType 行为相同。

代码示例

如果你已经在基于 .NET 4.5 的桌面或者 Web 端应用程序中使用了反射机制,原有的 API 仍然可以使用,并且会与新的 API 共存,但新的 API 提供了更轻量级的实现。TypeInfo 使用 IEnumerable 泛型集合来构建元数据,而不是传统的数组。这使得 TypeInfo 可以支持使用 Lazy 方式遍历对象元数据,并且可以引入 LINQ 来使查询更加便捷。

我们先来看下使用传统 API 来检索 Type 元数据的方式。Type API 可以提供检索类型名称、名空间、类型全名称、所在模块等信息。API 结构与 .NET 4.0 中一致。

       Type studentType = typeof(Student);
string studentAssembly = studentType.Assembly.FullName;
string studentFullName = studentType.FullName;
string studentNameSpace = studentType.Namespace;
string studentModule = studentType.Module.FullyQualifiedName;

正如你所看到的,Type 提供了对象结构的基本视图。如果你需要对类的结构挖掘的更新一些,现在可以使用新的 TypeInfo API。可以通过 GetTypeInfo() 方法从 Type 获取其 TypeInfo 定义。

我们先定义一个 Student 类:

   public class Student
{
public string Name { get; set; }
public int Class { get; set; }
public int GetTestReport() { return ; }
public event EventHandler Running;
}

现在,假如说你需要查看 Student 类中定义的属性、方法、事件等,可以通过 TypeInfo 提供的 API 获得。

       TypeInfo studentInfo = studentType.GetTypeInfo();
IEnumerable<PropertyInfo> declaredProperties = studentInfo.DeclaredProperties;
IEnumerable<MethodInfo> declaredMethods = studentInfo.DeclaredMethods;
IEnumerable<EventInfo> declaredEvents = studentInfo.DeclaredEvents;

另一个常见的反射方式是查找程序集内定义的所有类型。在 API 变化之后,Assembly.DefinedTypes 将返回一个 TypeInfo 的集合,而不是 Type 数组。

       Assembly thisAssembly = typeof(Student).GetTypeInfo().Assembly;
IEnumerable<TypeInfo> allDefinedTypes = thisAssembly.DefinedTypes;

TypeInfo 除了提供上面描述的属性,还提供了若干用于获取元数据信息的方法。

参考资料

在 .NET 4.5 中反射机制的变更的更多相关文章

  1. .NET中反射机制的使用与分析

    .NET中反射机制的使用与分析 [日期:2008-06-30] 来源:  作者:志伟     .NET反射的定义:审查元数据并收集关于它的类型信息的能力. 元数据是一种二进制信息,用以对存储在公共语言 ...

  2. Java中反射机制和Class.forName、实例对象.class(属性)、实例对象getClass()的区别

    一.Java的反射机制   每个Java程序执行前都必须经过编译.加载.连接.和初始化这几个阶段,后三个阶段如下图:   其中

  3. JAVA中反射机制一

    反射一 基本概念 一.反射机制的基本概念 什么是反射?反射是指在运行状态中,对于任意一个类,都可以获取到这个类的所有属性和方法:对于任意一个对象,都能够调用这个对象的任意方法和属性:这种动态获取信息及 ...

  4. Java中反射机制详解

    序言 在学习java基础时,由于学的不扎实,讲的实用性不强,就觉得没用,很多重要的知识就那样一笔带过了,像这个马上要讲的反射机制一样,当时学的时候就忽略了,到后来学习的知识中,很多东西动不动就用反射, ...

  5. android中反射机制

    本文介绍Android反射机制实现与原理,在介绍之前,要和Java进行比较,所以先看下Java中的反射相关知识: 一.反射的概念及在Java中的类反射 反射主要是指程序可以访问.检测和修改它本身状态或 ...

  6. spring中反射机制和注入的使用

    http://www.cnblogs.com/andin/archive/2011/04/30/spring.html spring的一大核心概念是注入, 但是,这存在的一个前提就是类是由spring ...

  7. JAVA中反射机制五(java.lang.reflect包)

    一.简介 java.lang.reflect包提供了用于获取类和对象的反射信息的类和接口.反射API允许对程序访问有关加载类的字段,方法和构造函数的信息进行编程访问.它允许在安全限制内使用反射的字段, ...

  8. JAVA中反射机制六(java.lang.reflect包)

    一.简介 java.lang.reflect包提供了用于获取类和对象的反射信息的类和接口.反射API允许对程序访问有关加载类的字段,方法和构造函数的信息进行编程访问.它允许在安全限制内使用反射的字段, ...

  9. JAVA中反射机制四

    声明:如需转载请说明地址来源:http://www.cnblogs.com/pony1223 反射四 利用反射获取类的属性 1.通过反射也可以获取到类中的属性,假设我们继续使用Person这个类,然后 ...

随机推荐

  1. java集合类(二)

    第十六天知识点总结 一.泛型 泛型:java jdk 1.5 新特性. 泛型的好处: 1.运行时的错误提前到编译时. 2.避免无谓的强制类型转换 自定义方法泛型:自定义泛型就是一个数据类型的占位或一个 ...

  2. 关于DCOM的安全性

    关于DCOM的安全性 DCOM的安全性设置在注册表中. 2. 通过DCOMCNF.exe可以配置

  3. VS2008的DLL项目添加了方法但是找不到怎么办?

      VS2008中建立了一个DLL项目,使用了一段时间后,在其中一个类中添加了一个方法,然后编译后,拷贝了新的.h文件到使用DLL的项目中,并且.dll和.lib也拷贝到了需要的位置,但是在目标项目中 ...

  4. RMQ(范围最值问题)算法学习

    RMQ算法适合求解对一个数组多次查询给定范围内的最值. 预处理操作: 令d[i,j]表示从i开始,长度为2^j的一段元素的最值,可以用递推公式写出d[i,j] = min{ d[i][j-1], d[ ...

  5. C++基于TCP和UDP的socket通信

    以下是关于socket编程的一个非常经典的例子: 服务端: #include <stdio.h> #include <Winsock2.h> //windows socket的 ...

  6. VC++ 标准C++中的string类的用法总结

    相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用.但是如果离开了MFC框架,还有没有这样使用起来非常方便的类呢?答案是肯 ...

  7. iOS相关思考题

    1.iOS如何应对APP版本升级,数据结构随之变化? 一般程序app升级时,数据库有可能发生改变,如增加表字段,增加表等. 此时有两种操作: 1 就是毫无留情的把本地旧数据库直接删掉,重新建立新的数据 ...

  8. SQL数据库完全复制

    很少摸 Windows 环境下的东西,最近被个 MS SQL Server 的数据库搞得头大.实在不像 MySQL 那样用起来轻车熟路, OrZ ... 本来以为企业管理器里面既然提供了 DTS 数据 ...

  9. centos6.5 安装cmake 3.3.2

    os:centos6.5 cmake版本:3.3.2 安装编译源码所需的工具和库 yum install gcc gcc-c++ ncurses-devel perl 下载cmake 使用wget工具 ...

  10. JProfiler使用入门(一)——准备工作

      JProfiler是一个全功能的Java剖析工具(profiler),主要用于检查和跟踪系统(限于Java开发的)的性能. JProfiler可以通过时时的监控系统的内存使用情况,随时监视垃圾回收 ...