Domanda

Sto cercando di analizzare gli oggetti in XML in Delphi, quindi ho letto di chiamare il metodo ClassInfo dell'oggetto per ottenere le sue informazioni RTTI.

Il fatto è che apparentemente funziona solo con oggetti TPersistent. Altrimenti, devo aggiungere specificamente una direttiva del compilatore {$ M +} al codice sorgente affinché il compilatore generi informazioni RTTI.

Quindi ho aggiunto felicemente la direttiva, solo per scoprire che, anche se restituiva qualcosa dalla chiamata ClassInfo (usato per restituire zero), ora non riesco a recuperare le proprietà, i campi o i metodi della classe da essa. È come se avesse creato l'oggetto vuoto.

Qualche idea su cosa mi sto perdendo qui? Grazie!

È stato utile?

Soluzione

Hai inserito tali proprietà e metodi nella sezione pubblicata ?

Oltre a ciò, RTTI 'classico' ($ TYPEINFO ON) ti fornirà solo informazioni sulle proprietà, non sui metodi. È necessario RTTI "esteso" ($ METHODINFO ON) per quelli.

Buon punto di partenza per RTTI esteso: David Glassborow su RTTI esteso

(chi potrebbe credere che proprio in questo momento ho finito di scrivere del codice che utilizza RTTI esteso e ho deciso di sfogliare un po 'lo Stack Overflow :))

Altri suggerimenti

RTTI ti mostrerà solo le proprietà pubblicate , ecc. - non solo quelli pubblici.

Prova il tuo codice con un oggetto TOB e vedi cosa succede - se non funziona, pubblica il tuo codice perché non tutti sono psichici.

Hai preso in considerazione l'utilizzo del componente TXMLDocument? Guarderà il tuo XML e quindi creerà una bella unità di classi Delphi che rappresenta il tuo file XML - lo rende davvero, davvero facile da leggere e scrivere file XML.

Per quanto riguarda il problema RttiType che restituisce solo uno zero, ciò probabilmente si verifica per un motivo: nel test, non è stata creata un'istanza della classe in qualsiasi momento. Il compilatore, poiché non ha mai un riferimento a questa classe (perché non è affatto un'istanza), semplicemente lo rimuove dalle informazioni come forma di ottimizzazione. Vedi i due esempi seguenti. Il comportamento è diverso quando la classe viene istanziata a un certo punto nel codice o meno.

Supponiamo che la seguente classe:

type
  TTest = class
  public
    procedure Test;
  end;

e il seguente codice di seguito:

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;

finora, le informazioni sulla classe TTest non sono disponibili per l'uso da RTTI. Tuttavia, quando creiamo ad un certo punto, all'interno dell'applicazione, viene creato un riferimento per esso all'interno della compilazione, che rende disponibili queste informazioni:

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;

A quel punto, se usi LContext.FindType ('TTest') , non ci sarà un ritorno nullo, perché il compilatore ha mantenuto il riferimento alla classe. Questo spiega il comportamento che stavi avendo nei tuoi test.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top