Delphi.NET 内部实现分析(3.3)
来源:百度文库 编辑:神马文学网 时间:2024/05/16 18:23:20
2.3. 对象
接下来我们看看类的实例,对象的实现
//-----------------------------------------Borland.Delphi.System.pas--
type
TObject = System.Object;
TObjectHelper = class helper for TObject
procedure Free;
function ClassType: TClass;
class function ClassName: string;
class function ClassNameIs(const Name: string): Boolean;
class function ClassParent: TClass;
class function ClassInfo: TObject;
class function InheritsFrom(AClass: TClass): Boolean;
class function MethodAddress(const Name: string): TObject;
class function SystemType: System.Type;
function FieldAddress(const Name: string): TObject;
procedure Dispatch(var Message);
end;
//-----------------------------------------Borland.Delphi.System.pas--
从Borland.Delphi.System的定义中我们可以看到,TObject实际上就是System.Object的
别名而已,而真正的代码是通过class helper给TObject也就是System.Object打的补丁。
下面我们来仔细看看TObjectHelper的实现代码,理解Delphi是如何移植到CLR上的。
//-----------------------------------------Borland.Delphi.System.pas--
procedure TObjectHelper.Free;
begin
if (Self <> nil) and (Self is IDisposable) then
(Self as IDisposable).Dispose;
end;
//-----------------------------------------Borland.Delphi.System.pas--
与传统Delphi的用户自行管理内存模式不同,Delphi.NET使用CLR提供的自动内存管理机制,
有GC垃圾回收机制自动回收无用的内存。
但为了给用户一个自行控制外部资源(如文件句柄,网络连接)等稀缺资源的机会,CLR同时提供了
IDisposable接口这种妥协机制。一个类如果实现了IDisposable接口,则说明其有需要自己管理
生命周期的资源,可以通过IDisposable.Dispose方法手工释放。接口定义如下
IDisposable = interface
procedure Dispose;
end;
因而Delphi.NET的Free方法只是简单检测当前对象是否支持IDisposable接口,如支持则
直接调用IDisposable.Dispose释放资源。不过目前预览版对此接口的支持好像不是很好用 :(
如果以后能够支持象C#中using语句那样的功能就好了,呵呵
在TObjectHelper的实现中可以看到,对类方法如class function方法来说,
Self就是指向类的元类,因而ClassParent和ClassInfo方法直接从其元类获取信息。
//-----------------------------------------Borland.Delphi.System.pas--
class function TObjectHelper.ClassParent: TClass;
begin
Result := _TClass(Self).ClassParent;
end;
class function TObjectHelper.ClassInfo: TObject;
begin
Result := _TClass(Self).FInstanceType;
end;
//-----------------------------------------Borland.Delphi.System.pas--
而对于普通的方法,则需要将其转换为Token或Type再进行处理。ClassType和FieldAddress
就是两个很好的例子。前者使用刚刚提到的_GetMetaFromHandle函数从当前对象的类型Token
获取元类;后者则从当前对象的类型Type(CLR中类似元类的概念)获取指定名称字段的对象
//-----------------------------------------Borland.Delphi.System.pas--
function TObjectHelper.ClassType: TClass;
begin
Result := _GetMetaFromHandle(System.Type.GetTypeHandle(Self));
end;
function TObjectHelper.FieldAddress(const Name: string): TObject;
begin
Result := TypeOf(Self).GetField(Name);
end;
//-----------------------------------------Borland.Delphi.System.pas--
剩余方法的实现原理大同小异,无非是在对象、类、元类、Token和Type之间互相转换,获取所需的信息。
//-----------------------------------------Borland.Delphi.System.pas--
class function TObjectHelper.SystemType: System.Type;
begin
Result := System.Type.GetTypeFromHandle(_TClass(Self).FInstanceType);
end;
class function TObjectHelper.ClassName: string;
begin
Result := System.Type.GetTypeFromHandle(_TClass(Self).FInstanceType).Name;
end;
class function TObjectHelper.ClassNameIs(const Name: string): Boolean;
begin
Result := ClassName = Name;
end;
class function TObjectHelper.InheritsFrom(AClass: TClass): Boolean;
begin
Result := TypeOf(Self).IsInstanceOfType(TypeOf(AClass));
end;
class function TObjectHelper.MethodAddress(const Name: string): TObject;
begin
Result := TypeOf(Self).GetMethod(Name);
end;
//-----------------------------------------Borland.Delphi.System.pas--
余下一个TObjectHelper.Dispatch方法,后面分析Delphi.NET消息模型时再详谈。
接下来我们看看类的实例,对象的实现
//-----------------------------------------Borland.Delphi.System.pas--
type
TObject = System.Object;
TObjectHelper = class helper for TObject
procedure Free;
function ClassType: TClass;
class function ClassName: string;
class function ClassNameIs(const Name: string): Boolean;
class function ClassParent: TClass;
class function ClassInfo: TObject;
class function InheritsFrom(AClass: TClass): Boolean;
class function MethodAddress(const Name: string): TObject;
class function SystemType: System.Type;
function FieldAddress(const Name: string): TObject;
procedure Dispatch(var Message);
end;
//-----------------------------------------Borland.Delphi.System.pas--
从Borland.Delphi.System的定义中我们可以看到,TObject实际上就是System.Object的
别名而已,而真正的代码是通过class helper给TObject也就是System.Object打的补丁。
下面我们来仔细看看TObjectHelper的实现代码,理解Delphi是如何移植到CLR上的。
//-----------------------------------------Borland.Delphi.System.pas--
procedure TObjectHelper.Free;
begin
if (Self <> nil) and (Self is IDisposable) then
(Self as IDisposable).Dispose;
end;
//-----------------------------------------Borland.Delphi.System.pas--
与传统Delphi的用户自行管理内存模式不同,Delphi.NET使用CLR提供的自动内存管理机制,
有GC垃圾回收机制自动回收无用的内存。
但为了给用户一个自行控制外部资源(如文件句柄,网络连接)等稀缺资源的机会,CLR同时提供了
IDisposable接口这种妥协机制。一个类如果实现了IDisposable接口,则说明其有需要自己管理
生命周期的资源,可以通过IDisposable.Dispose方法手工释放。接口定义如下
IDisposable = interface
procedure Dispose;
end;
因而Delphi.NET的Free方法只是简单检测当前对象是否支持IDisposable接口,如支持则
直接调用IDisposable.Dispose释放资源。不过目前预览版对此接口的支持好像不是很好用 :(
如果以后能够支持象C#中using语句那样的功能就好了,呵呵
在TObjectHelper的实现中可以看到,对类方法如class function方法来说,
Self就是指向类的元类,因而ClassParent和ClassInfo方法直接从其元类获取信息。
//-----------------------------------------Borland.Delphi.System.pas--
class function TObjectHelper.ClassParent: TClass;
begin
Result := _TClass(Self).ClassParent;
end;
class function TObjectHelper.ClassInfo: TObject;
begin
Result := _TClass(Self).FInstanceType;
end;
//-----------------------------------------Borland.Delphi.System.pas--
而对于普通的方法,则需要将其转换为Token或Type再进行处理。ClassType和FieldAddress
就是两个很好的例子。前者使用刚刚提到的_GetMetaFromHandle函数从当前对象的类型Token
获取元类;后者则从当前对象的类型Type(CLR中类似元类的概念)获取指定名称字段的对象
//-----------------------------------------Borland.Delphi.System.pas--
function TObjectHelper.ClassType: TClass;
begin
Result := _GetMetaFromHandle(System.Type.GetTypeHandle(Self));
end;
function TObjectHelper.FieldAddress(const Name: string): TObject;
begin
Result := TypeOf(Self).GetField(Name);
end;
//-----------------------------------------Borland.Delphi.System.pas--
剩余方法的实现原理大同小异,无非是在对象、类、元类、Token和Type之间互相转换,获取所需的信息。
//-----------------------------------------Borland.Delphi.System.pas--
class function TObjectHelper.SystemType: System.Type;
begin
Result := System.Type.GetTypeFromHandle(_TClass(Self).FInstanceType);
end;
class function TObjectHelper.ClassName: string;
begin
Result := System.Type.GetTypeFromHandle(_TClass(Self).FInstanceType).Name;
end;
class function TObjectHelper.ClassNameIs(const Name: string): Boolean;
begin
Result := ClassName = Name;
end;
class function TObjectHelper.InheritsFrom(AClass: TClass): Boolean;
begin
Result := TypeOf(Self).IsInstanceOfType(TypeOf(AClass));
end;
class function TObjectHelper.MethodAddress(const Name: string): TObject;
begin
Result := TypeOf(Self).GetMethod(Name);
end;
//-----------------------------------------Borland.Delphi.System.pas--
余下一个TObjectHelper.Dispatch方法,后面分析Delphi.NET消息模型时再详谈。
Delphi.NET 内部实现分析(3.3)
Delphi.NET 内部实现分析(1)
Delphi.NET 内部实现分析(2)
Delphi.NET 内部实现分析(3.1)
Delphi.NET 内部实现分析(3.2)
Delphi.NET 内部实现分析(3.4)
Delphi.NET 内部实现分析(4)
Delphi.NET 内部实现分析(5)
Delphi.NET 内部实现分析(5)
Delphi.NET 内部实现分析(4)
Delphi.NET 内部实现分析(3.4)
PAM 的应用开发和内部实现源码分析
Delphi中PING的实现
Delphi和Java实现webservice
用DELPHI实现为NT添加用户
Delphi中PING的实现ewe
Delphi中PING的实现a
Delphi屏幕截图技术实现2
Delphi屏幕截图技术实现d
使用.NET实现断点续传
在Delphi中实现VFP6的查询速度 - Delphi - 文档中心 - 源码天空
浅析多层结构及其在Delphi中的实现<一>
Delphi中不使用第三方控件实现XP风格
DELPHI的RTTI实现数据集的简单对象化