欢迎来到.net学习网

欢迎联系站长一起更新本网站!QQ:879621940

您当前所在位置:首页 »  .NET本质论第一卷:公共语言运行库教程 » 正文

本教程章节列表
最新评论

用类型编程-运行时的类型(2)

创建时间:2012年09月10日 15:58  阅读次数:(6024)
分享到:
isinst和castclas都是在利用被RunTimeTypeHandle引用的数据结构。尽管这个数据结构(在内部被称为CORINFO_CLASS_STRUCT)没有正式的文档说明,但它包含了许多关键的信息。如图4.2所示,每个类型都有一张接口表( interface table)。它包含了类型所兼容的每个接口的入口项。

图1

在类型的接口表中的每个入口项包含了用于支持该接口的类型句柄。对接口类型的转换将通过这张表进行匹配。为了支持向直接或间接基类型的转换,这个数据结构还包台了一个指针,指向类型元数据的内存表示,而它则包括 一个指向该类型的基类型元数据的指针。对于直接或问接基类型的强制转换,将会使用该数据结构的这个部分进行匹配。对于这两种情况,类犁兼容性测试只是通过接口表进行简单的线性检索( lincar search),接着通过元数据结构链表进行线性遍历(linear traversal)。这意味着,对于支持大量接口或者多级基类型(注意,不是多重继承,.net的一个类型最多只有一个基类型。这里的多级继承,是指一个类型有一个基类型,而它的基类型还可能有基类型,如此往复。)(或者两者都有)的类型,类型兼容性的运行时测试将比只支持少量接口或者扁平的类型层次结构(或者两者都有)的简单类型要慢得多。

每种编程语言都以自己的方式公开isinst和castclass操作码。在C#中,isinst操作码通过as和is关键字公开。as关键字是个二元操作符,它接收一个变量和一个类型名。C#接着发射(emjt)适合的isinst指令,并且将返回的引用作为操作符的结果。考虑下面的示例:
Static void Operate(Ipatient p)
{
Ibillee b=p as Ibillee;
If(b==null)
AskForFederalFunds();
}

c#的iS操作符的工作方式与as相似,只是最后结果的引用变成了个布尔值,它的值取决于引用是否为空。下面是使开is操作符的同样代码:
static voia Operate (IPatient p)  {
bool isBillee = p is IBillee;  //这是 isinst指令
if(!isBillee)
AskForFederalFunds() ;
}

这段代码在语义上等价于前面的示例。不同的是在第二个示例中IBillee引用是小可用的。
C#通过其强制类型转换操作符公开castclass操作码。c#强制类型转换使用和C同样的语法。考虑下面的示例
static voia Operate (IPatient p)  {
try
{
Ibillee b=(Ibillee)p;
}
Catch (System.InvalidCastExcePtion ex)
AskForFedaralFunds ( ) ;
}

注意,存这个示例中,有一个异常处理程序将被用于处理潜在的失败。再次考虑到异常相对较高的开销,如果强制转换不能保证总是成功的,那么采用isinst操作码的构件要更台适一些。

尽管对于基于CLR工的程序员来说,类型句枘和其引用的数据结构根本是不透明的,但存储在这个数据结构(以及该类型的下纽元数据)上的大多数信息可以由程序员通过System.Type类型访问到。
System.Type基于底层优化后的类型信息,向程序员提供了易于使用的外观(facade)。你可以通过调用System.Type的静态方法GetTypeFromHandle,从类型句柄获取个System.Type对象,也可以通过System.Type的TypeHandle属性还原类型句柄。

每种编程语言都提供了种自己的机制,用于将符号化类型名转换为System.Type对象。任c#中可以用typeof操作符。typeof操作符接收一个符号化的类型名,得到的结果是一个该类型的System.Type对象的引用。下面演示了typecf操作符的使用:

图2

对于一个给定的类型,CLR保证在内存中恰好只有一个System.Type对象存在。这意味着在这个示例中,type和t2被保让引用的是同一个System.Type对象。

上述例子假定所需要的类型名在编译阶段时是有效的。此外,所请求类型的程序集会变成该模块和程序集的静态依赖项7。为了不用静态依赖项便支持类型的动态加载,首先需要使用assernbly.Load或Assembly。LoadFrom动态地加载该类型的程序集,在该程序集被加载后,你就可以使用Assembly对象的GetType方法提取想要得到的类型。下面的代码与前面的示例在语义上是等价的:

图3袕L?0郪dk (W
来源:.net学习网
说明:所有来源为 .net学习网的文章均为原创,如有转载,请在转载处标注本页地址,谢谢!
【编辑:Wyf】

打赏

取消

感谢您的支持,我会做的更好!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

最新评论

共有评论0条
  • 暂无任何评论,请留下您对本文章的看法,共同参入讨论!
发表评论:
留言人:
内  容:
请输入问题 92+94=? 的结果(结果是:186)
结  果: