如何区分老派`对象'和'记录'?

时间:2013-10-08 02:55:43

标签: delphi delphi-xe2 rtti

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中工作

2 个答案:

答案 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