2011-10-19 13 views
2

TListにさまざまなレコードタイプのポインタが多数ある場合、TList内の異なるレコードの値にアクセスするにはどうすればよいですか?Delphi XEのポインタによるレコードの型情報の取得方法は?

これらの参照されたレコードのレコードタイプまたはタイプ情報を取得する方法はありますか?

私は現在Delphi XEを使用しています。

+0

私はRTTIについて何も知らないが、レコードへのポインタは型情報をそれらと一緒に運ぶとは思わない。私が間違っている? –

+0

このPRECord(List [i])^。メンバーはPRecordが^ Yourdefinedrecordです...私は本当に質問を理解していません... – opc0de

+1

@ opc0de私はあなたがどのタイプリストにあるそれ以外の場合は、あなたのコメントと同じくらい些細なことです。 –

答えて

6

異なるレコードタイプには共通のヘッダーが必要です。次に、そのヘッダータイプへのリストアイテムポインターをキャストして、次にキャストするレコードタイプを決定することができます。例:

type 
    TRecType = (recA, recB, recC); 

    PRecHeader = ^TRecHeader; 
    TRecHeader = record 
    RecType: TRecType; 
    ... 
    end; 

    PRecordA = ^TRecordA; 
    TRecordA = record 
    Header: TRecHeader; 
    IntValue: Integer; 
    end; 

    PRecordB = ^TRecordB; 
    TRecordB = record 
    Header: TRecHeader; 
    StrValue: String; 
    end; 

    PRecordC = ^TRecordC; 
    TRecordC = record 
    Header: TRecHeader; 
    DblValue: Double; 
    end; 

var 
    PRec: Pointer; 
begin 
    PRec := List[Index]; 
    case PRecHeader(PRec)^.RecType of 
    recA: use PRecordA(PRec)^.IntValue as needed ... 
    recB: use PRecordB(PRec)^.StrValue as needed ... 
    recC: use PRecordC(PRec)^.DblValue as needed ... 
    end; 
end; 
+1

バリアントレコードを再実装するのではなく、単に使用するほうがはるかに簡単です。 –

+0

バリアントレコードであっても、バリアントデータのどの部分にアクセスするかを知るためには、バリアント領域外のヘッダー値が必要です。 –

+0

はい、構文ははるかにクリーンです。もちろん、文字列のような管理された型を使用している場合、バリアント型レコードは使用できません。 –

3

これは本当にできません。 Delphiオブジェクトとは異なり、レコードにはRTTIはありません。さまざまなタイプのデータを混在させ、実行時にどのタイプのデータであるかを知りたい場合は、単にオブジェクトを使用するだけです。オブジェクトは、TObject.ClassTypeを継承し、他のいくつかこの作業を簡単にするためのルーチン。

本当に何らかの理由でレコードを使用する必要がある場合は、変更されないカスタムタグで各レコードを開始する必要があります。私はシステムを説明しようとしていましたが、Remyが私にそれを打つように見えます。しかし、これには十分なオーバーヘッドが伴い、オブジェクトを代わりに使用することもできます。この道をはるか遠くに行くと、基本的にはTObjectの多くを再実装しています。

1

ContnrsユニットのTObjectListオブジェクトを使用することを強くお勧めします。 (これはまだDelphi XEにありますか?)これはTListに基づいていますが、ポインタの代わりにTObjectの参照を提供するための作業はあります。これは微妙な違いですが、isas演算子をリストの項目に直接使用することができます。

+2

'TObjectList'はまだXEにありますが、レコードポインタではあまり役に立ちません。 –

+0

@TOndrej私は、タイプ情報を持たないレコードから離れていくことを提案していると思います。 –

1

{$ M +}?でオブジェクトパスカルスタイルを使用することはどうですか?これはTObjectのオーバーヘッドを排除します

+2

ここには良い答えがあるかもしれませんが、いくらか精巧化が必要です –

関連する問題