知识大全 对.NET Framework 反射的反思[3]
Posted 类型
篇首语:我不是天生的王者,但我骨子里流着不服输的血液。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 对.NET Framework 反射的反思[3]相关的知识,希望对你有一定的参考价值。
对.NET Framework 反射的反思[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
动态调用代码
迄今为止 我已经获得运行时对象的句柄(如类型和方法) 仅作描述用 例如输出它们的名称 但是如何做得更多呢?如何实际调用某个方法呢?
此例的几个要点是 首先 从一个 MyClass mc 实例检索一个 System Type 实例 然后 从该类型检索一个 MethodInfo 实例 最后 当调用 MethodInfo 时 通过把它作为调用的第一个参数来传递 将其绑定到另一个 MyClass (mc ) 实例中
前面讲过 对于您预期在源代码中见到的类型和对象使用之间的区别 这个示例使这种区别变得模糊 逻辑上 您检索了一个方法的句柄 然后调用该方法 就象它属于一个不同的对象一样 对于熟悉函数式编程语言的程序员来说 这可能轻而易举;但对于只熟悉 C# 的程序员来说 要分离对象实现和对象实例化 可能就不是那么直观了
组合在一起
至此我已经探讨过检查和调用的基本原理 接下来我会用具体的例子把它们组合在一起 设想您希望交付一个库 带有必须处理对象的静态帮助器函数 但在设计的时候 您对这些对象的类型没有任何概念!这要看函数调用方的指示 看他希望如何从这些对象中提取有意义的信息 函数将接受一个对象集合 和一个方法的字符串描述符 然后它将遍历该集合 调用每个对象的方法 用一些函数聚合返回值
就此例而言 我要声明一些约束条件 首先 字符串参数描述的方法(必须由每个对象的底层类型实现)不会接受任何参数 并将返回一个整数 代码将遍历对象集合 调用指定的方法 逐步计算出所有值的平均值 最后 因为这不是生产代码 在求和的时候我不用担心参数验证或整数溢出
在浏览示例代码时 可以看到主函数与静态帮助器 ComputeAverage 之间的协议除了对象自身的通用基类之外 并不依赖任何类型信息 换句话说 您可以彻底改变正在传送的对象的类型和结构 但只要总是能使用字符串描述一个方法 且该方法返回整数 ComputeAverage 就可以正常工作!
需要注意的一个关键问题跟隐藏在最后这个例子中的 MethodInfo(一般反射)有关 注意 在 ComputeAverage 的 foreach 循环中 代码只从集合中的第一个对象中抓取一个 MethodInfo 然后绑定用于所有后续对象的调用 正如编码所示 它运行良好 — 这是 MethodInfo 缓存的一个简单例子 但此处有一个根本性的局限 MethodInfo 实例仅能由其检索对象同等层级类型的实例调用 因为传入了 IntReturner 和 SonOfIntReturner(继承自 IntReturner)的实例 才能这样运行
在示例代码中 已经包含了名为 EnemyOfIntReturner 的类 它实现了与其他两个类相同的基本协议 但并没有共享任何常见共享类型 换句话说 该接口逻辑上等同 但在类型层级上没有重叠 要探讨 MethodInfo 在该情形下的使用 请尝试向集合添加其他对象 通过 new EnemyOfIntReturner( ) 得到一个实例 再次运行示例 您会遇到一个异常 指出 MethodInfo 不能用于调用指定的对象 因为它和获得 MethodInfo 时的原始类型完全无关(即使方法名称和基本协议是等同的) 要使您的代码达到生产水准 您需要做好遇到这一情形的准备
一个可能的解决方案可以是通过自己分析所有传入对象的类型 保留对其共享的类型层级(如果有)的解释 如果下一对象的类型与任意已知类型层级相异 就需要获取和存储一个新的 MethodInfo 另一解决方案是捕获 TargetException 并重新获取一个 MethodInfo 实例 这里提到的两种解决方案都各有其优缺点 Joel Pobar 为本杂志 五月期写过一篇优秀的文章 内容关于 MethodInfo 缓冲和我所极力推荐的反射性能
希望此示例演示的向应用程序或框架中添加反射 可以为日后的自定义或可扩展性增加更多的灵活性 不可否认 较之本机编程语言中的同等逻辑 使用反射可能会有些繁琐 如果您感到对您或您的客户来说 向代码中添加基于反射的后期绑定过于麻烦(毕竟他们需要以某种方式在您的框架中说明他们的类型和代码) 那么可能仅需要适度的灵活性以取得某种平衡
序列化的高效类型处理 至此我们已通过若干示例讲述了 NET 反射的基本原理 接下来让我们看一下现实世界中的情形 如果您的软件通过 Web 服务或其他进程外远程技术与其他系统进行交互 那么您很可能已经遇到序列化问题 序列化本质上是将活动的 占用内存的对象 转变成适合线上传输或磁盘存储的数据格式 NET Framework 中的 System Xml Serialization 命名空间提供了拥有 XmlSerializer 的强大序列化引擎 它可以使用任意托管对象 并将其转换成 XML(日后也可将 XML 数据转换回类型化的对象实例 这一过程称之为反序列化) XmlSerializer 类是一种强大的 企业就绪的软件片断 如果您在项目中面临序列化问题 它将是您的首选 但为了教学目的 我们来探讨如何实现序列化(或者其他类似的运行时类型处理实例) 设想情形 您正在交付一个框架 需要使用任意用户类型的对象实例 并将其转换成某种智能型数据格式 例如 假定有一个驻留内存的对象 类型为如下所示的 Address (pseudocode)class Address AddressID id; String Street City; StateType State; ZipCodeType ZipCode; 如何生成适当的数据表示形式以方便日后使用?或许一个简单的文本呈现将解决这一问题 Address: Street: Microsoft Way City: Redmond State: WA Zip:
cha138/Article/program/net/201311/15774相关参考
对.NETFramework反射的反思[1] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 清晰
对.NETFramework反射的反思[4] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 如果
知识大全 .Net Framework 2.0范型的反射使用[3]
.NetFramework2.0范型的反射使用[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
知识大全 .Net Framework 2.0范型的反射使用
.NetFramework2.0范型的反射使用 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 在
知识大全 .Net Framework 2.0范型的反射使用[1]
.NetFramework2.0范型的反射使用[1] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
知识大全 .Net Framework 2.0范型的反射使用[2]
.NetFramework2.0范型的反射使用[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
介绍.NETFramework3.0新特性 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 描述N
.NETFramework3.0框架慨述 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!本文将简要介
知识大全 ADO.NET Entity Framework 试水——并发[3]
ADO.NETEntityFramework试水——并发[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来
知识大全 使用.NET Framework中新的日期时间类型[3]
使用.NETFramework中新的日期时间类型[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧