TRTTIProperty.SetValue( ) は TValue インスタンスを受け取りますが、提供された TValue インスタンスが別のタイプのプロパティに基づいている場合、問題が発生します。
例えば
TMyObject = class
published
property StringValue: string read FStringValue write FStringValue;
end;
procedure SetProperty(obj: TMyObject);
var
context: TRTTIContext;
rtti: TRTTIType;
prop: TRTTIProperty;
value: TValue;
begin
context := TRTTIContext.Create;
rtti := context.GetType(TMyObject);
prop := rtti.GetProperty('StringValue');
value := 1000;
prop.SetValue(obj, value);
end;
値を文字列にキャストしようとしてもうまくいきません。
prop.SetValue(obj, value.AsString);
prop.SetValue(obj, value.Cast(prop.PropertyType.Handle));
これを解決する方法についてのアイデアはありますか?
アップデート:
なぜ整数を文字列に代入する必要があるのかと疑問に思う方もいらっしゃると思いますが、説明を試みます。(実際には、文字列を整数に割り当てたい可能性が高いですが、それはあまり関係ありません...)
私が達成しようとしているのは、GUI とモデルの間の一般的な「仲介者」を作ることです。どういうわけかテキスト編集フィールドをプロパティにフックしたい。私が持っているモデルごとにそのような仲介者を作る代わりに、新しい RTTI/TValue が私にとって魔法のように働くことを願っていました。
私はジェネリックも初めてなので、ジェネリックがどのように役立つかわかりません。動的に決定された型で実行時にジェネリックをインスタンス化することは可能ですか、それともコンパイルで知る必要がありますか?
例えば
TMyGeneric<T> = class
end;
procedure DoSomething( );
begin
prop := rtti.getProperty('StringValue');
mygen := TMyGeneric<prop.PropertyType>.Create;
//or
mygen := TMyGeneric<someModel.Class>.Create;
end;
魔法の時代はまだ来ていないのかもしれません... いくつかの大きなケース構造で対処できると思います...