TRTTIProperty.SetValue()接受一个TValue实例,但是如果提供的TValue实例基于不同的类型,那么属性就会爆炸。
E.g。
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对我有用。
我也是仿制药的新手,所以我不确定仿制药是如何帮助的。是否可以在运行时使用动态决定的类型实例化泛型,或者编译是否需要知道?
E.g。
TMyGeneric<T> = class
end;
procedure DoSomething( );
begin
prop := rtti.getProperty('StringValue');
mygen := TMyGeneric<prop.PropertyType>.Create;
//or
mygen := TMyGeneric<someModel.Class>.Create;
end;
也许魔法的时代还未到来......我想我可以管理几个大案例结构......
答案 0 :(得分:5)
TValue不是Variant。您只能读取“您”放入其中的数据类型。
TValue.Cast不起作用,因为它与隐式类型转换具有相同的语义。您不能将整数分配给字符串,反之亦然。但是您可以为float指定一个整数,或者可以为int64指定一个整数。
答案 1 :(得分:0)
现在不能尝试,但我会写:
value := '1000';
prop.SetValue(obj, value);
答案 2 :(得分:0)
试
prop.SetValue(obj, value.ToString)
但对我来说,问题与弗朗索瓦一样。为什么要使用错误的数据类型值设置属性?