Pregunta

Estoy tratando de analizar objetos a XML en Delphi, así que leí acerca de llamar al método ClassInfo del objeto para obtener su información RTTI.

La cuestión es que esto aparentemente solo funciona para objetos TPersistent. De lo contrario, tengo que agregar específicamente una directiva del compilador {$ M +} al código fuente para que el compilador genere información RTTI.

Así que felizmente agregué la directiva, solo para encontrar que, incluso si devolvió algo de la llamada ClassInfo (solía devolver nil), ahora no puedo recuperar las propiedades, campos o métodos de la clase. Es como si hubiera creado el objeto vacío.

¿Alguna idea de lo que me estoy perdiendo aquí? Gracias!

¿Fue útil?

Solución

¿Puso esas propiedades y métodos en la sección publicada ?

Además de eso, el RTTI 'clásico' ($ TYPEINFO ON) solo le brindará información sobre las propiedades, no sobre los métodos. Necesita RTTI 'extendido' ($ METHODINFO ON) para esos.

Buen punto de partida para RTTI extendido: David Glassborow en RTTI extendido

(¿quién creería que en este momento terminé de escribir un código que usa RTTI extendido y decidí navegar un poco por el Desbordamiento de pila :))

Otros consejos

RTTI solo le mostrará propiedades publicadas , etc. - no solo los públicos.

Pruebe su código con un TObject y vea qué sucede; si eso no funciona, publique su código porque no todos son psíquicos.

¿Ha considerado usar el componente TXMLDocument? Observará su XML y luego creará una buena unidad de clases de Delphi que representa su archivo XML, lo que hace que sea muy, muy fácil de leer y escribir archivos XML.

En cuanto al problema RttiType que devuelve solo cero, esto probablemente ocurre por una razón: en su prueba, no creó una instancia de la clase en ningún momento. El compilador, porque nunca tiene una referencia a esta clase (porque no es una instancia en absoluto), simplemente lo elimina de la información como una forma de optimización. Vea los dos ejemplos a continuación. El comportamiento es diferente cuando tiene la clase instanciada en algún momento de su código o no.

Suponga la siguiente clase:

type
  TTest = class
  public
    procedure Test;
  end;

y el siguiente código a continuación:

var
  LContext: TRttiContext;
  LType: TRttiType;
  LTest: TTest;
begin
  LContext := TRttiContext.Create;
  for LType in LContext.GetTypes do
  begin
    if LType.IsInstance then
    begin
      WriteLn(LType.Name);
    end;
  end;
end;

hasta ahora, la información de la clase TTest no está disponible para su uso por RTTI. Sin embargo, cuando creamos en algún momento, dentro de la aplicación, se crea una referencia para ella dentro de la compilación, lo que hace que esta información esté disponible:

var
  LContext: TRttiContext;
  LType: TRttiType;
  LTest: TTest;
begin
  LTest := TTest.Create; //Here i´m using TTest.
                         //Could be in another part of the program

  LContext := TRttiContext.Create;
  for LType in LContext.GetTypes do
  begin
    if LType.IsInstance then
    begin
      WriteLn(LType.Name);
    end;
  end;
end;

En ese punto, si usa LContext.FindType ('TTest') , no habrá un retorno nulo, porque el compilador mantuvo referencia a la clase. Esto explica el comportamiento que estaba teniendo en sus pruebas.

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