Delphi 2010: New RTTI, setting propertyvalue to arbitary value
TRTTIProperty.SetValue( ) takes an TValue instance, but if the provided TValue instance is based on a different type then the property, things blow up.
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;
Trying to cast the value to a string w开发者_StackOverflow社区ont work either.
prop.SetValue(obj, value.AsString);
prop.SetValue(obj, value.Cast(prop.PropertyType.Handle));
Any ideas on how solve this?
UPDATE:
Some of you wonder why I want to assign an integer to an string, and I will try to explain. (Actually, it's more likely that I want to assign a string to an integer, but that's not that relevant...)
What I'm trying to accomplish, is to make a general 'middle-man' between gui and model. I want to somehow hook a textedit field to an property. Instead of making such an middle man for each model that I have, I hoped that the new RTTI/TValue thing would work some magic for me.
I'm also new to generics, so I'm not sure how generics could have helped. Is it possible to instantiate a generic at runtime with a dynamically decided type, or do the compile need to know?
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;
Maybe the age of magic has yet to come... I guess I can manage with a couple of big case structures...
TValue is not a Variant. You can only read the datatype that "you" put into it.
TValue.Cast doesn't work because it has the same semantic that implicit type casts have. You cannot assign an integer to a string or vice versa. But you can assign an integer to a float, or you can assign an integer to a int64.
Can't try it right now, but I would have written:
value := '1000';
prop.SetValue(obj, value);
try
prop.SetValue(obj, value.ToString)
But for me it is same question as for François. Why you want to set the property with a value of the wrong datatype?
精彩评论