转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
Delphi.NET 内部实现分析(3.2)         ★★★★

Delphi.NET 内部实现分析(3.2)

作者:闵涛 文章来源:闵涛的学习笔记 点击数:776 更新时间:2009/4/23 18:35:34

 Delphi.NET 内部实现分析(3.2)

首先我们来看看元类的定义与实现
//-----------------------------------------Borland.Delphi.System.pas--
type
  TObject = System.Object;

  _TClass = class;

  TClass = class of TObject;

  _TClass = class
  protected
    FInstanceType: System.RuntimeTypeHandle;
    FClassParent: _TClass;
  public
    constructor Create; overload;
    constructor Create(ATypeHandle: System.RuntimeTypeHandle); overload;
    constructor Create(AType: System.Type); overload;
    function ClassParent: TClass; virtual;
  end;

  TClassHelperBase = class(TObject)
  public
    FInstance: TObject;
  end;
//-----------------------------------------Borland.Delphi.System.pas--
  上一节我们大概分析过元类的实现原理。每一个类有一个对应的嵌套子类,
名称为@Meta前缀加上类名,此类从Borland.Delphi.System._TClass类继承出来,
在实现上类似TClassHelperBase,只不过FInstance是类一级的静态成员变量。

  .class /*0200000D*/ auto ansi nested public beforefieldinit @MetaTDemo
         extends Borland.Delphi.System.@TClass/* 02000003 */
  {
    .field /*0400000E*/ public static class HelloUnit.TDemo/* 02000005 *//@MetaTDemo/* 0200000D */ @Instance

    .method /*06000027*/ private hidebysig specialname rtspecialname static
            void  .cctor() cil managed
    .method /*06000026*/ public hidebysig specialname rtspecialname
            instance void  .ctor() cil managed
    .method /*06000008*/ public instance void
            Hello() cil managed
  }

  元类的静态构造函数如上一节中的@MetaTDemo..cctor()函数,构造一个元类的实例
放入元类的@Instance静态成员

  private static TDemo.@MetaTDemo..cctor() {
    TDemo.@MetaTDemo.@Instance = new @MetaTDemo..ctor();
  }

  元类的构造函数则载入自己类型的Token到FInstanceType字段中。

  public TDemo.@MetaTDemo..ctor() : base() {
    this.FInstanceType = Token of TDemo;
  }

  这个Token在CLR中起到索引的作用,用以在Metadata诸多表中定位特定的表项,
每种元素如类、方法、字段、属性等等都有其自己的Token。在BCL中Token表现为
RuntimeTypeHandle类型,用于诸如Type.GetTypeFromHandle之类函数,
可以通过Type.TypeHandle获取。
  关于Token的重要性及物理实现上用法请参加前面提到的我对Metadata分析的文章。

  元类这里保存的FInstanceType实际上就是类似于Delphi中VMT指针的索引。
//-----------------------------------------Borland.Delphi.System.pas--
constructor _TClass.Create;
begin
  inherited Create;
end;

constructor _TClass.Create(ATypeHandle: System.RuntimeTypeHandle);
begin
  inherited Create;
  FInstanceType := ATypeHandle;
end;

constructor _TClass.Create(AType: System.Type);
begin
  Create(AType.TypeHandle);
end;
//-----------------------------------------Borland.Delphi.System.pas--
  可以看到_TClass的几种形式构造函数,实际上都是围绕着这个Token做文章。
//-----------------------------------------Borland.Delphi.System.pas--
function _TClass.ClassParent: TClass;
begin
  if not Assigned(FClassParent) then
    FClassParent := _TClass.Create(System.Type.GetTypeFromHandle(FInstanceType).BaseType.TypeHandle);
  Result := FClassParent;
end;
//-----------------------------------------Borland.Delphi.System.pas--
  而_TClass.FClassParent则是在需要时填充的父类的元类。注意这里的转换Token到
CLR中类型的方法。System.Type.GetTypeFromHandle函数和后面要使用到的
System.Type.GetTypeHandle函数完成Type与Token之间的双向转换。
  因此可以说在Delphi.NET中,元类实际上就是对类的Token的一个封装。

  在了解了元类的实现后,我们来看看如何从一个Token获取其元类。
//-----------------------------------------Borland.Delphi.System.pas--
var
  MetaTypeMap: Hashtable;

function _GetMetaFromHandle(ATypeHandle: System.RuntimeTypeHandle): _TClass;
var
  t: System.Type;
begin
  if not Assigned(MetaTypeMap) then
    MetaTypeMap := Hashtable.Create;

  Result := _TClass(MetaTypeMap[ATypeHandle]);
  if not Assigned(Result) then
  begin
    t := System.Type.GetTypeFromHandle(ATypeHandle);
    t := t.GetNestedType(''''@Meta'''' + t.name, BindingFlags(Integer(BindingFlags.Public) or
      Integer(BindingFlags.NonPublic)));
    if Assigned(t) then
    begin
      Result := _TClass(t.GetField(''''@Instance'''').GetValue(nil));
      MetaTypeMap.Add(ATypeHandle, Result);
    end
    else
    begin
      Result := _TClass.Create(ATypeHandle);
    end;
  end;
end;
//-----------------------------------------Borland.Delphi.System.pas--
  Delphi.NET使用一个哈希表MetaTypeMap来缓存Token到元类的转换关系,
因为这种转换是耗时且较频繁的操作,这主要是为优化现有Delphi代码对元类的大量使用。
  对一个Token,Delphi.NET先将其转换为一个Type类型,然后取其嵌套子类,
子类名就是@Meta前缀加类名,元类允许是公开或私有。
  如果找到元类的类型,则从元类的@Instance字段获取值,也就是元类的一个实例;
否则使用此Token构造一个新的元类并返回。
  这样Delphi.NET就完成了TClass机制在CLR环境下的映射。


[C语言系列]NET 中C#的switch语句的语法  [系统软件]托拽Explore中的文件到VB.net的窗口
[系统软件]Boost库在XP+Visual C++.net中的安装  [常用软件]新配色面板:Paint.Net3.0RC1官方下载
[常用软件]用内建的“Net Meeting”聊天  [VB.NET程序]Henry的VB.NET之旅(三)—共享成员
[VB.NET程序]Henry的VB.NET之旅(二)—构造与析构  [VB.NET程序]Henry的VB.NET之旅(一)—失踪的窗体
[VB.NET程序]在托盘上显示Balloon Tooltip(VB.NET)  [VB.NET程序]Henry手记-VB.NET中动态加载Treeview节点(二)
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台