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

Foi útil?

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?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top