分享
 
 
 

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

王朝delphi·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

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环境下的映射。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有