3

Delphi 2010 で一種のオブジェクト/レコード シリアライザーを作成しようとしていますが、レコードがバリアント レコードであるかどうかを検出する方法があるかどうか疑問に思っています。たとえば、Types.pas で定義されている TRect レコード:

TRect = record
case Integer of
  0: (Left, Top, Right, Bottom: Longint);
  1: (TopLeft, BottomRight: TPoint);
end; 

シリアライザーはデータ構造に対して再帰的に動作する必要があるため、TPoint レコードに降りて、シリアライズされたファイルに冗長な情報を生成します。レコードの詳細情報を取得することで、これを回避する方法はありますか?

4

1 に答える 1

1

1つの解決策は次のようになります。

procedure SerializeRecord (RttiRecord : TRttiRecord)

var
  AField : TRttiField;
  Offset : Integer;

begin
Offset := 0;
for AField in RttiRecord.Fields do
  begin
  if AField.Offset < Offset then Exit;
  Offset := AField.Offset; //store last offset
  SerializeField (AField);
  end;
end;

しかし、この解決策はすべての場合に適切な解決策ではありません。異なるバリアントに同じ情報と同じタイプが含まれている場合にのみ、シリアル化に対して機能します。次のようなものがある場合(wikipedia.orgから):

type   
  TVarRec = packed record
  case Byte of
    0: (FByte: Byte;
        FDouble: Double);
    1: (FStr: ShortString);
  end;

シリアル化しますか

FByte=6
FDouble=1.81630607010916E-0310

またはシリアル化する方が良いでしょうか

FStr=Hello!

はい、確かに、これはコンピュータでも同じですが、人間が読み取りまたは編集できるはずのファイルでは同じではありません。

したがって、問題を解決する唯一の方法は、属性を使用して、シリアル化に使用するバリアントを定義することだと思います。

于 2010-05-04T07:02:13.207 に答える