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 和模型之间建立一个通用的“中间人”。我想以某种方式将文本编辑字段 Hook 到属性。我没有为我拥有的每个模型创建一个中间人,而是希望新的 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;
也许魔法时代还没有到来...我想我可以处理几个大的案例结构...
最佳答案
TValue 不是变体。您只能读取“您”放入其中的数据类型。
TValue.Cast 不起作用,因为它具有与隐式类型转换相同的语义。您不能将整数分配给字符串,反之亦然。但是您可以将整数分配给 float ,也可以将整数分配给 int64。
关于Delphi 2010 : New RTTI, 将属性值设置为任意值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1603427/