program Project15;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.Rtti, System.TypInfo;
type
TRecord = record
public
AField: integer;
constructor Init(test: integer);
end;
TOldObject = object
public
AField: integer;
constructor Init(test: integer);
procedure Fancy; virtual; <<--- compiles
class operator Implicit(test: TRecord): TOldObject; <<-- does not compile.
end;
procedure IsObjectARecord;
var
ARecord: TRecord;
AObject: TOldObject;
v: TValue;
s: String;
begin
v:= TValue.From(ARecord);
case v.Kind of
tkRecord: WriteLn('it''s a Record');
end;
ARecord:= TRecord.Init(10);
AObject.Init(10);
v:= TValue.From(AObject);
case v.Kind of
tkRecord: begin
WriteLn('object is a record?');
if v.IsObject then s:= 'true'
else s:= 'false';
WriteLn('isObject = ' + s);
WriteLn('ToString says: '+v.ToString);
end;
end;
end;
{ TOldSkool }
constructor TOldObject.Init(test: integer);
begin
AField:= 10;
end;
constructor TRecord.Init(test: integer);
begin
AField:= 10;
end;
begin
IsObjectARecord;
Readln;
end.
测试过程的结果如下:
ARecord是一张唱片 AObject是一个记录?
isObject(AObject)= false
AObject.ToString说:(记录)
然而object
&lt;&gt; record
从功能的角度来看
对象支持继承和虚拟调用
Record支持类操作符。
有没有办法使用RTTI分辨TP5.5对象和记录?
甚至还需要区分他们 - ? -
请注意,我不打算使用object
,我只是使用RTTI枚举类型,以便我的带有指针的通用HashTable可以自行清理。
是的我知道默认情况下该对象存在于堆栈中(或者需要特别努力的堆)并且通常不需要被释放。
如果有人知道为什么使用TP5.5对象的虚拟调用不再有效,他们曾经在Delphi 2007中工作
答案 0 :(得分:1)
旧对象已弃用。
所以你不应该将它与新的rtti一起使用。
弃用的第一步是禁止虚拟方法。因为我想编译回归。
这是Embarcadero决定模仿C#和他的结构/类范例。错误的决定imho。
答案 1 :(得分:1)
据我所知,在Delphi的RTTI框架中,旧式对象无法与记录区分开来。这个程序
{$APPTYPE CONSOLE}
uses
System.Rtti;
type
TOldObject = object
end;
var
ctx: TRttiContext;
RttiType: TRttiType;
begin
RttiType := ctx.GetType(TypeInfo(TOldObject));
Writeln(TValue.From(RttiType.TypeKind).ToString);
Writeln(RttiType.IsRecord);
Readln;
end.
输出
tkRecord TRUE