Delphi 2010: Nova RTTI, definindo o valor da propriedade para o valor arbitrário
-
05-07-2019 - |
Pergunta
TRTTIProperty.SetValue () recebe uma instância TValue, mas se a instância TValue fornecida baseia-se em um tipo diferente, em seguida, a propriedade, as coisas explodir.
por exemplo.
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;
Tentando converter o valor para um não vai funcionar corda também.
prop.SetValue(obj, value.AsString);
prop.SetValue(obj, value.Cast(prop.PropertyType.Handle));
Algumas ideias sobre como resolver isso?
UPDATE:
Alguns de vocês perguntam por que eu quero atribuir um inteiro para uma string, e eu vou tentar explicar. (Na verdade, é mais provável que eu quero atribuir uma string para um inteiro, mas isso não é tão relevante ...)
O que eu estou tentando fazer, é fazer um 'meio-homem' geral entre gui e modelo. Eu quero de alguma forma ligar um campo textedit a uma propriedade. Em vez de fazer um homem tão média para cada modelo que eu tenho, eu esperava que a coisa nova RTTI / TValue iria trabalhar alguma mágica para mim.
Eu também sou novo para os genéricos, então eu não sei como os genéricos poderiam ter ajudado. É possível instanciar um genérico em tempo de execução com um tipo decidiu de forma dinâmica, ou a necessidade de compilação de saber?
por exemplo.
TMyGeneric<T> = class
end;
procedure DoSomething( );
begin
prop := rtti.getProperty('StringValue');
mygen := TMyGeneric<prop.PropertyType>.Create;
//or
mygen := TMyGeneric<someModel.Class>.Create;
end;
Talvez a idade de magia ainda está para vir ... Eu acho que eu posso administrar com um par de grandes estruturas de caso ...
Solução
TValue não é um Variant. Você só pode ler o tipo de dados que "você" colocar nele.
TValue.Cast não funciona porque tem a mesma semântica que moldes tipo implícito tem. Você não pode atribuir um inteiro para uma string ou vice-versa. Mas você pode atribuir um inteiro para um float, ou você pode atribuir um inteiro para um int64.
Outras dicas
Não é possível experimentá-lo agora, mas eu teria escrito:
value := '1000';
prop.SetValue(obj, value);
try
prop.SetValue(obj, value.ToString)
Mas para mim é a mesma pergunta como por François. Por que você quer definir a propriedade com um valor de tipo de dados errado?