Delphi 2010: Nouveau RTTI, définition de la valeur de la propriété sur une valeur arbitraire

StackOverflow https://stackoverflow.com/questions/1603427

  •  05-07-2019
  •  | 
  •  

Question

TRTTIProperty.SetValue () prend une instance de TValue, mais si l’instance fournie par TValue est basée sur un type différent de celui de la propriété, les choses s’agrandiront.

ex.

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;

Essayer de convertir la valeur en chaîne ne fonctionnera pas non plus.

prop.SetValue(obj, value.AsString);
prop.SetValue(obj, value.Cast(prop.PropertyType.Handle));

Des idées sur la façon de résoudre ce problème?

MISE À JOUR:

Certains d’entre vous se demandent pourquoi je veux attribuer un entier à une chaîne et je vais essayer de vous expliquer. (En fait, il est plus probable que je veuille assigner une chaîne à un entier, mais ce n'est pas très pertinent ...)

Ce que j'essaie d'accomplir, c'est de créer un «intermédiaire» général entre l'interface graphique et le modèle. Je veux en quelque sorte accrocher un champ textedit à une propriété. Au lieu de créer un tel intermédiaire pour chaque modèle que j’ai, j’espérais que le nouveau système RTTI / TValue ferait quelque chose de magique pour moi.

Je suis également novice dans le domaine des génériques. Je ne sais donc pas comment les génériques auraient pu aider. Est-il possible d'instancier un générique au moment de l'exécution avec un type choisi de manière dynamique ou la compilation doit-elle savoir?

ex.

TMyGeneric<T> = class
end;

procedure DoSomething( );
begin
  prop := rtti.getProperty('StringValue');
  mygen := TMyGeneric<prop.PropertyType>.Create;
  //or
  mygen := TMyGeneric<someModel.Class>.Create;
end;

Peut-être que l'âge de la magie n'est pas encore venu ... Je suppose que je peux me débrouiller avec deux grosses structures de boîtiers ...

Était-ce utile?

La solution

TValue n'est pas une variante. Vous ne pouvez lire que le type de données que vous "utilisez". mettre dedans.

TValue.Cast ne fonctionne pas car il a la même sémantique que les conversions de types implicites. Vous ne pouvez pas affecter un entier à une chaîne ni inversement. Mais vous pouvez affecter un entier à un float ou un entier à un entier64.

Autres conseils

Je ne peux pas l'essayer pour l'instant, mais j'aurais écrit:

  value := '1000'; 
  prop.SetValue(obj, value);

essayer

prop.SetValue (obj, value.ToString)

Mais pour moi c'est la même question que pour François. Pourquoi voulez-vous définir la propriété avec une valeur du type de données incorrect?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top