2009-10-21 6 views
4

TRTTIProperty.SetValue() prend une instance TValue, mais si l'instance TValue fournie est basée sur un type différent de la propriété, les choses explosent.Delphi 2010: Nouvelle valeur RTTI, valeur de propriété affectée à une valeur arbitraire

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; 

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 pour résoudre ce problème?

MISE À JOUR:

Certains d'entre vous me demande pourquoi je veux attribuer un entier à une chaîne, et je vais essayer d'expliquer. (En fait, il est plus probable que je veuille assigner une chaîne à un nombre entier, mais ce n'est pas pertinent ...)

Ce que j'essaie d'accomplir, c'est de faire un 'intermédiaire' général entre gui et le modèle. Je veux en quelque sorte accrocher un champ textedit à une propriété. Au lieu de faire un tel intermédiaire pour chaque modèle que j'ai, j'espérais que la nouvelle chose RTTI/TValue ferait un peu de magie pour moi. Je suis aussi nouveau dans le domaine des génériques, donc je ne suis pas sûr de savoir 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 décidé de façon dynamique, ou la compilation doit-elle savoir?

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; 

Peut-être l'âge de la magie est encore à venir ... Je suppose que je peux gérer avec deux grandes structures de cas ...

+0

Qu'attendriez-vous qu'il se produise, si cela était "résolu"? Un entier n'est pas une chaîne, alors que * devrait * se produire lorsque vous essayez de stocker un entier dans une propriété typée par une chaîne? "Les choses explosent" me semble assez raisonnable. –

+0

Il s'attend très probablement à ce qu'il contienne la valeur '1000', comme Andreas l'a laissé entendre dans sa réponse. –

+0

Ont ajouté quelques informations sur ce que j'essaie de faire. Je suppose que je m'attends à beaucoup ... – Vegar

Répondre

5

La valeur de TValue n'est pas une variante. Vous pouvez seulement lire le type de données que "vous" avez mis dedans.

TValue.Cast ne fonctionne pas car il a la même sémantique que celle des types implicites. Vous ne pouvez pas affecter un entier à une chaîne ou vice versa. Mais vous pouvez assigner un entier à un float, ou vous pouvez assigner un entier à un int64.

0

Ne peut pas l'essayer en ce moment, mais j'aurais écrit:

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

essayer

prop.SetValue(obj, value.ToString)

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