0
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 : (record)

ただし、 object<>record機能の観点から。
オブジェクトは継承と仮想呼び出しをサポートしています。
Record はクラス演算子をサポートしています。

RTTI を使用して TP5.5 オブジェクトとレコードを区別する方法はありますか?
それらを区別する必要さえありますか?

を使用する予定はないことに注意してくださいobject。RTTI を使用して型を列挙しているだけなので、ポインターを含む汎用の HashTable はそれ自体を適切にクリーンアップできます。
はい、オブジェクトはデフォルトでスタック(または特別な努力を払ってヒープ)に存在し、通常は解放する必要がないことを知っています。

Delphi 2007 で動作していた TP5.5 オブジェクトを使用した仮想呼び出しが機能しなくなった理由を誰かが知っている場合のボーナス ポイント

4

2 に答える 2

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
真実
于 2013-10-10T12:48:09.410 に答える