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 和模型之间建立一个一般的“中间人”。我想以某种方式将 textedit 字段连接到属性。我希望新的 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 不起作用,因为它具有与隐式类型转换相同的语义。您不能将整数分配给字符串,反之亦然。但是您可以将整数分配给浮点数,也可以将整数分配给 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 回答