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

原创 2004年03月03日 11:37:00

 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();
  }

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

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

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

  
元类这里保存的FInstanceType实际上就是类似于DelphiVMT指针的索引。
//-----------------------------------------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
函数完成TypeToken之间的双向转换。
  
因此可以说在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代码对元类的大量使用。
  
对一个TokenDelphi.NET先将其转换为一个Type类型,然后取其嵌套子类,
子类名就是@Meta前缀加类名,元类允许是公开或私有。
  
如果找到元类的类型,则从元类的@Instance字段获取值,也就是元类的一个实例;
否则使用此Token构造一个新的元类并返回。
  
这样Delphi.NET就完成了TClass机制在CLR环境下的映射。

Zookeeper内部分析

分析Zookeeper内部如何做到分布式数据一致性,将从系统模型、序列化与协议、客户端工作原理、会话、服务端工作原理及数据存储来分析Zookeeper技术底层实现。...
  • tang06211015
  • tang06211015
  • 2016年07月15日 22:58
  • 4946

java中HashMap详解(从源码角度看内部实现)

HashMap 和 HashSet 是 Java Collection Framework 的两个重要成员,其中 HashMap 是 Map 接口的常用实现类,HashSet 是 Set 接口的常用实...
  • free4294
  • free4294
  • 2014年08月07日 15:53
  • 7411

【深度探索STL】详解 vector 内部机制

前面初步介绍了序列式容器 vector :初识序列式容器vector,这里试图通过简单剖析源码来了解 vector 的内部机制,参考资料:《STL 源码剖析》(侯捷)...
  • yeswenqian
  • yeswenqian
  • 2014年02月23日 23:59
  • 2124

asp.net 利用VB内部机制实现图像格式转换源码

  • 2009年11月16日 20:45
  • 2KB
  • 下载

digbook.net___深入研究Windows内部原理系列之十二:网络协议的构成和实现

  • 2009年12月28日 22:57
  • 8.47MB
  • 下载

asp.net实现小区物业内部管理网

  • 2008年11月25日 22:26
  • 1.57MB
  • 下载

.NET源码的内部排序实现

使用JetBrains的DotPeek工具可以方便地查看.net的部分源码。于是看了一下.NET的内部是如何实现排序的算法。 在System.Collections.Generic 命名空间下可以看...
  • cuit
  • cuit
  • 2014年06月22日 11:42
  • 1120

asp.net 文件批量选取,批量上传,带进度条,uploadify3.2

最近朋友请帮忙写一个批量上传图片的程序,之前在做一个系统的时候由于时间有限没有多研究,这次花了些时间,总算是可以了。 在现实文件上传进度的同时还要将这些数据上传到文件夹或者数据库,所以就需要异步...
  • wangyizhi58
  • wangyizhi58
  • 2013年03月22日 10:54
  • 3804

jQuery上传插件Uploadify 3.2在.NET下的详细例子

项目中要使用Uploadify 3.2来实现图片上传并生成缩略通的功能,特此记下来,以供各位参考! Uploadify下载地址:http://www.uploadify.com/download...
  • my98800
  • my98800
  • 2017年12月04日 09:56
  • 93

RDIFramework.NET平台代码生成器V3.2版本全新发布(提供下载-免费使用)

RDIFramework.NET代码生成器V3.2版本修改了针对3.0版本的框架部分做了大量的调整,在V3.1版本增加对MySql数据库的支持,支持生成Web部分的UI代码(WebForm,MVC),...
  • chinahuyong
  • chinahuyong
  • 2017年02月27日 16:09
  • 3783
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Delphi.NET 内部实现分析(3.2)
举报原因:
原因补充:

(最多只允许输入30个字)