【C#/笔记】反射Reflection

反射Reflection

  • 程序集(Assemblies)与命名空间(namespaces)

    • 命名空间
      提供了一个逻辑组织系统,是唯一识别的一套名字,用来避免在命名的冲突。

    • 程序集
      是.NET程序的部署单元,用于物理包装和配置,像一个类型的容器,可以包含类别(元数据信息)、用于实现这些类型的可执行代码(IL)、资源和对于其他程序集合的链接。
      有两种主要种类:应用程序(.exe)和库(.dll),前者有一个主入口而后者没有。

      关于程序集可参阅这篇

  • 反射定义
    审查元数据并收集关于它的类型信息的能力。(关于元数据在特性attribute这一篇有说明,即一类自我描述性数据)
    审查这一过程我看到比较好理解的例子应该就是B超了,在不对对象本身做直接干扰的情况下获取对象的基本信息。

  • 作用
    可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访问其字段和属性。
    即:

    1. 它允许在运行时查看特性(attribute)信息。
    2. 它允许审查集合中的各种类型,以及实例化这些类型。
    3. 它允许延迟(晚)绑定的方法和属性(property)。
    4. 它允许在运行时(动态)创建新类型,然后使用这些类型执行一些任务。

    这里需要重点关注的就是动态。对于C#这类静态类型语言,许多工作可以在编译阶段完成,这样安全性和执行效率都可以得到保证,然而有时候也会出于灵活性设计需要使用晚绑定,在运行阶段进行一些操作,这时候就需要用到反射。

  • 优缺点
    优点:

    1. 降低耦合性,提高了程序的灵活性和扩展性,提高自适应能力。
    2. 它允许程序创建和控制任何类的对象,无需提前硬编码目标类。
      缺点:
    3. 性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。
    4. 使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。
  • 具体用法
    反射用到的命名空间:
    System、System.Reflection

    反射用到的主要类:
    System.Type 类--通过这个类可以访问任何给定数据类型的信息。
    System.Reflection.Assembly类--它可以用于访问给定程序集的信息,或者把这个程序集加载到程序中。

    反射的用途:

    1. 使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。
    2. 使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。
    3. 使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。
    4. 使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。
    5. 使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。
    6. 使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。
    7. 使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。
    8. 使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。
  • 基本使用方法

    1. 调用本地类型中的方法
      Type t= Type.GetType(“test”) ; //获取class
      MethodInfo method = t.GetMethod(“DebugMsg”); //获取方法信息
      object o= Activator.CreateInstance(t); //生成实例
      method.Invoke(o, null); //调用方法

    2. 调用外部dll中的方法
      Assembly ass = Assembly.LoadFile(“path/XXX.dll”); //获取dll
      Type t= ass.GetType(“test”) ; //获取程序集中对应class
      后面同上

    关于C#中反射使用更详细的内容可参阅这篇

参考资料:
1. http://www.runoob.com/csharp/csharp-reflection.html
2. https://blog.csdn.net/qiaoquan3/article/details/51423890
3. 《C#API》

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页