T
に値をキャストするTValue
のAsType<T>
メソッドを使用します。
lValue := prop.GetValue(aInst);
Result.AddStrings(TRTTIHelpers<T>.DoGetValuesForRecord(lValue.AsType<T>));
この単純なプログラムは、このことを示しています。もちろん
{$APPTYPE CONSOLE}
uses
System.RTTI;
type
TMyRecord = record
foo: Integer;
end;
TMyClass = class
function GetRec: TMyRecord;
property Rec: TMyRecord read GetRec;
function GetInt: Integer;
property Int: Integer read GetInt;
end;
function TMyClass.GetRec: TMyRecord;
begin
Result.foo := 42;
end;
function TMyClass.GetInt: Integer;
begin
Result := 666;
end;
procedure Main;
var
inst: TMyClass;
ctx: TRttiContext;
typ: TRttiType;
prop: TRttiProperty;
value: TValue;
rec: TMyRecord;
begin
inst := TMyClass.Create;
typ := ctx.GetType(TypeInfo(TMyClass));
for prop in typ.GetProperties do begin
if prop.Name='Rec' then begin
value := prop.GetValue(inst);
rec := value.AsType<TMyRecord>;
Writeln(rec.foo);
end;
end;
end;
begin
try
Main;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
を、このプロパティprop
がであることを必要としません正しいタイプ。そうでなければ、実行時エラーが発生します。上記の例では、プロパティの名前をテストして、目的のプロパティが確実に取得されるようにしています。このテストを削除すると、実行時にプログラムが失敗し、EInvalidCast
エラーが発生します。
あなたのコードを見ると、あなたはそのようなエラーに遭遇する可能性が高いと私は思っています。 rt
のすべてのプロパティが同じタイプであった場合、私には驚くかもしれません。
TRTTIHelpers<T>
私はそれが現在のフォームであなたにとって非常に有用とは思わないと思う。少なくともRTTIに基づいたコードとはうまくやりとりできません。 TRTTIHelpers<T>
を呼び出す理由は、コンパイル時に型パラメータを指定する必要があるためです。しかし、RTTIコードでは、コンパイル時にその型を知ることはできません。私はTRTTIHelpers<T>
がおそらくジェネリッククラスではないはずで、代わりにRTTI型を使用して、実行時に決定された型付けに対して柔軟な機能を提供すると考えています。もちろん、このアドバイスは間違っているかもしれませんが、私は、私を導く質問には小さなコード抜粋しかありません。
これはあなたが尋ねた質問に対する答えです。実行時エラーは 'lValue'にあるものは' T'型ではないことを伝えています。 –
lValueに含まれるものはTRTTIRecordType型です - prop.PropertyTypeがTRttiRecordTypeの場合 - クラスにレコード型があります – RBA
はい、レコード型です。実行時エラーが通知するので、一般的な 'T'と同じ型である必要はありません。 –