4

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;

魔法の時代はまだ来ていないのかもしれません... いくつかの大きなケース構造で対処できると思います...

4

3 に答える 3

5

TValueはバリアントではありません。「あなた」が入力したデータ型のみを読み取ることができます。

TValue.Castは、暗黙的な型キャストと同じセマンティクスを持っているため、機能しません。文字列に整数を割り当てたり、その逆を行うことはできません。ただし、floatに整数を割り当てることも、int64に整数を割り当てることもできます。

于 2009-10-21T20:51:09.897 に答える
0

今すぐ試すことはできませんが、次のように書いていました。

  value := '1000'; 
  prop.SetValue(obj, value);
于 2009-10-21T20:44:55.730 に答える
0

試す

prop.SetValue(obj, value.ToString)

しかし、私にとってはフランソワと同じ質問です。プロパティに間違ったデータ型の値を設定したいのはなぜですか?

于 2009-10-22T07:30:00.677 に答える