现在的位置: 首页 > 综合 > 正文

跨 AppDomain 边界访问对象之类型转换原则

2012年04月19日 ⁄ 综合 ⁄ 共 1544字 ⁄ 字号 评论关闭

    我在使用 .NET Remoting 的 Wellkown 方式实例化一个服务器对象并将该对象通过 Console.WriteLine 输出到控制台时发现:应用程序引发了一个异常,异常的原因是 Console.WriteLine 函数内部将客户端实例化的 TransparentProxy 对象成功转换为 IFormattable 类型了,奇怪的是这个服务器对象并没有实现该接口。

 

    因此,我对 TransparentProxy 类型转换这块内容研究了一番,总结如下:

 

        1、CLR 在将 TransparentProxy 转换为目标类型时,通过调用

             RemotingServices.CheckCast(RealProxy rp, Type castType)

             函数实现类型检查,如果没有通过该函数的类型检,则将引发 

             Unable cast transparent proxy to type 的异常。

 

        2、CheckCast函数的内部首先判断 RealProxy 是否实现了IRemotingTypeInfo

             接口,如果是则调用其实现的CanCastTo函数。

 

        3、如果 RealProxy 没有实现该接口,则使用与其关联的ObjRef 中的 TypeInfo

            属性,该属性同样也实现了这个接口。

 

        4、.NET Remoting 中,默认的 RealProxy 类型是一个叫System.Runtime.Remoting.RemotingProxy

            的类型,其实现了 IRemotingTypeInfo 接口。该实现中提供

            了对.NET Remoting的 WellKown 支持。在该实现中调用了CanCastToWK

            函数,该函数包含了不会对接口进行类型检查的代码。

        5、CLR 将对象按引用封送到另一个 AppDomain 时,它会使用

             原始类型的元数据在目标 AppDomain 中定义一个 proxy类

             型,该类型包含了原始类型的所有成员(字段除外),然后实

             例化一个该类型(新定义的 proxy 类型)的对象返回给目标

             AppDomain 。也就是说,目标AppDomain 使用的是 proxy

             类型的实例。

 

        6、CLR 允许原始类型的引用变量指向被封送后的 proxy 实例,

             这是因为 proxy 实例的类型是由原始类型的元数据定义的。

             另外,对于 proxy.GetType()、is与 as 运算,它们都是将

             proxy 实例当作原始类型的实例来执行的。

 

        7、由于 proxy 类型不包含原始类型中字段的定义,因此

            CLR 将对 proxy 实例字段的访问封送为对

            System.Object.FieldGetter(string typeName, string fieldName, ref object val) 与

            System.Object.FieldSetter(string typeName, string fieldName, ref object val) 

            函数的调用,这两个函数内部都是通过 Reflection方式

            来进行字段读写的。因此,访问 proxy 实例字段的性能

            是非常差的(基于反射的访问,其性能是非常差劲的)。

 

抱歉!评论已关闭.