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 ...

War es hilfreich?

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?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top