Delphi 2010: Neue RTTI, das Setzen von Eigenschaftswert auf beliebigen Wert
-
05-07-2019 - |
Frage
TRTTIProperty.SetValue () nimmt eine TValue Instanz, aber wenn die bereitgestellte TValue-Instanz auf einem anderen Typ basiert dann die Eigenschaft, Dinge sprengen.
z.
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;
Der Versuch, den Wert in einen String zu werfen pflegt entweder arbeiten.
prop.SetValue(obj, value.AsString);
prop.SetValue(obj, value.Cast(prop.PropertyType.Handle));
Alle Ideen, wie diese lösen?
UPDATE:
Einige von euch fragen, warum ich eine ganze Zahl mit einem String zuweisen wollen, und ich werde versuchen zu erklären. (Eigentlich ist es wahrscheinlicher, dass ich eine Zeichenfolge in einer ganzen Zahl zuweisen will, aber das ist nicht so relevant ...)
Was ich versuche, zu tun ist einen allgemeinen ‚Mann in der Mitte‘ zwischen gui und Modell zu machen. Ich möchte irgendwie an eine Eigenschaft eines textedit Feld Haken. Statt zur Herstellung einer solchen mittleren Mann für jedes Modell, das ich habe, hoffte ich, dass die neue RTTI / TValue Sache für mich etwas Magie funktionieren würde.
Ich bin auch neu zu Generika, also bin ich nicht sicher, wie Generika dazu beigetragen haben könnte. Ist es möglich, eine generische zur Laufzeit mit einem dynamisch entschieden Typ, oder tun, um die Kompilierung Notwendigkeit zu instanziiert wissen?
z.
TMyGeneric<T> = class
end;
procedure DoSomething( );
begin
prop := rtti.getProperty('StringValue');
mygen := TMyGeneric<prop.PropertyType>.Create;
//or
mygen := TMyGeneric<someModel.Class>.Create;
end;
das Zeitalter der Magie Vielleicht hat noch zu kommen ... Ich glaube, ich mit ein paar großen Fall Strukturen verwalten können ...
Lösung
TValue ist kein Variant. Sie können nur den Datentyp lesen, dass „Sie“ in sie setzen.
TValue.Cast nicht funktioniert, weil es die gleiche semantische hat, dass implizite Typ Abgüsse haben. Sie können nicht für eine ganze Zahl in einen String oder umgekehrt zugeordnet werden. Aber man kann eine ganze Zahl mit einem Schwimmer zuweisen, oder Sie können eine ganze Zahl mit einem int64 zuweisen.
Andere Tipps
Kann versuchen, es jetzt nicht, aber ich würde geschrieben haben:
value := '1000';
prop.SetValue(obj, value);
Versuch
prop.SetValue(obj, value.ToString)
Aber für mich ist es gleiche Frage wie für François. Warum Sie mit einem Wert von dem falschen Datentyp der Eigenschaft setzen?