Delphi 2010: Nuevo RTTI, que establece el valor de la propiedad en un valor arbitrario

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

  •  05-07-2019
  •  | 
  •  

Pregunta

TRTTIProperty.SetValue () toma una instancia de TValue, pero si la instancia de TValue proporcionada se basa en un tipo diferente, entonces la propiedad, las cosas explotan.

Por ejemplo,

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;

Intentar convertir el valor en una cadena tampoco funcionará.

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

¿Alguna idea sobre cómo resolver esto?

ACTUALIZACIÓN:

Algunos de ustedes se preguntan por qué quiero asignar un número entero a una cadena, y trataré de explicarlo. (En realidad, es más probable que quiera asignar una cadena a un entero, pero eso no es tan relevante ...)

Lo que estoy tratando de lograr es hacer un "hombre medio" general entre la interfaz gráfica de usuario y el modelo. Quiero enganchar de alguna manera un campo de texto a una propiedad. En lugar de hacer un intermediario para cada modelo que tengo, esperaba que la nueva cosa RTTI / TValue funcionara un poco de magia para mí.

También soy nuevo en genéricos, así que no estoy seguro de cómo los genéricos podrían haber ayudado. ¿Es posible crear una instancia de un genérico en tiempo de ejecución con un tipo decidido dinámicamente, o la compilación debe saberlo?

Por ejemplo,

TMyGeneric<T> = class
end;

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

Tal vez la era de la magia aún no ha llegado ... Creo que puedo manejarlo con un par de grandes estructuras de casos ...

¿Fue útil?

Solución

TValue no es una variante. Solo puede leer el tipo de datos que '' usted '' poner en ella.

TValue.Cast no funciona porque tiene la misma semántica que tienen los tipos implícitos. No puede asignar un número entero a una cadena o viceversa. Pero puede asignar un entero a un flotante, o puede asignar un entero a un int64.

Otros consejos

No puedo probarlo ahora mismo, pero habría escrito:

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

prueba

prop.SetValue (obj, value.ToString)

Pero para mí es la misma pregunta que para François. ¿Por qué desea establecer la propiedad con un valor del tipo de datos incorrecto?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top