c#

位置:IT落伍者 >> c# >> 浏览文章

对.NET Framework 反射的反思[2]


发布日期:2021年11月07日
 
对.NET Framework 反射的反思[2]

另一种完全不同的情况是解释性编程语言总是通过主进程获得执行(脚本语言通常属于此类)由于程序的完整定义是可用的(作为输入源代码)并跟完整的语言实现结合在一起(作为解释器本身)因此所有支持自我分析所需的技术都到位了这种动态语言频繁地提供全面反射功能以及一组用于动态分析和操作程序的丰富工具

NET Framework CLR 和它的承载语言如 C# 属于中间形态编译器用来把源代码转换成 IL 和元数据后者与源代码相比虽属于较低级别或者较低逻辑性但仍然保留了很多抽象结构和类型信息一旦 CLR 启动和承载了此程序基类库 (BCL) 的 SystemReflection 库便可以使用此信息并返回关于对象类型类型成员成员签名等的信息此外它也可以支持调用包括后期绑定调用

NET 中的反射

要在用 NET Framework 编程时利用反射您可以使用 SystemReflection 命名空间此命名空间提供封装了很多运行时概念的类例如程序集模块类型方法构造函数字段和属性 中的表显示SystemReflection 中的类如何与概念上运行时的对应项对应起来

尽管很重要不过 SystemReflectionAssembly 和 SystemReflectionModule 主要用于定位新代码并将其加载到运行时本专栏中我暂不讨论这些部分并且假定所有相关代码都已经加载

要检查和操作已加载代码典型模式主要是 SystemType通常您从获得一个所关注运行时类别的 SystemType 实例开始(通过 ObjectGetType)接着您可以使用 SystemType 的各种方法在 SystemReflection 中探索类型的定义并获得其它类的实例例如如果您对某特定方法感兴趣并希望获得此方法的一个 SystemReflectionMethodInfo 实例(可能通过 TypeGetMethod)同样如果您对某字段感兴趣并希望获得此字段的一个 SystemReflectionFieldInfo 实例(可能通过 TypeGetField)

一旦获得所有必要的反射实例对象即可根据需要遵循检查或操作的步骤继续检查时您在反射类中使用各种描述性属性获得您需要的信息(这是通用类型吗?这是实例方法吗?)操作时您可以动态地调用并执行方法通过调用构造函数创建新对象等等

检查类型和成员

让我们跳转到一些代码中探索如何运用基本反射进行检查我将集中讨论类型分析从一个对象开始我将检索它的类型而后考察几个有意思的成员(请参见图 )

首先需要注意的是在类定义中乍看起来说明方法的篇幅比我预期的要多很多这些额外的方法是从哪里来的呢?任何精通 NET Framework 对象层次结构的人都会识别从通用基类 Object 自身继承的这些方法(事实上我首先使用了 ObjectGetType 检索其类型)此外您可以看到属性的 getter 函数现在如果您只需要 MyClass 自身显式定义的函数该怎么办呢?换句话说您如何隐藏继承的函数?或者您可能只需要显式定义的实例函数?

随便在线看看 MSDN就会发现大家都愿意使用 GetMethods 第二个重载方法它接受 BindingFlags 参数通过结合来自 BindingFlags 枚举中不同的值您可以让函数仅返回所需的方法子集替换 GetMethods 调用代之以

GetMethods(BindingFlagsInstance | BindingFlagsDeclaredOnly |BindingFlagsPublic)

结果是您得到以下输出(注意这里不存在静态帮助器函数和继承自 SystemObject 的函数)

Reflection Demo Example

Type Name: MyClass

Method Name: MyMethod

Method Name: MyMethod

Method Name: get_MyProperty

Property Name: MyProperty

如果您事先知道类型名称(完全限定)和成员又该如何?您如何完成从枚举类型向检索类型的转换?有了前两个示例中的代码您已经有了能够实现基元类浏览器的基本组件通过名称您可以找到一个运行时实体然后枚举其各种相关属性

[] [] [] []

               

上一篇:基于C#的接口基础教程之五

下一篇:对.NET Framework 反射的反思[1]