Pergunta
Eu estou tentando analisar objetos para XML em Delphi, assim que eu li sobre a chamada de método ClassInfo do objeto para obter suas informações de RTTI.
A coisa é, isso aparentemente só funciona para objetos TPersistent. Caso contrário, eu tenho que adicionar especificamente a diretiva de compilação {$ M +} para o código fonte para o compilador para gerar informações RTTI.
Então eu felizmente adicionado a directiva, apenas para descobrir que, mesmo se ele fez algo de retorno da chamada ClassInfo (é usado para retornar nil), agora eu não posso recuperar a classe propriedades, campos ou métodos a partir dele. É como se criou o objeto vazio.
Qualquer idéia do que estou em falta aqui? Obrigado!
Solução
Você colocar essas propriedades e métodos para a seção published
?
Além disso, 'clássica' RTTI ($ TypeInfo ON) só vai chegar informações sobre as propriedades, não em métodos. Você precisa 'estendido' RTTI ($ MethodInfo ON) para aqueles.
bom ponto de partida para RTTI estendida: David Glassborow em estendido RTTI
(quem acreditaria que apenas este minuto terminei de escrever algum código que usa estendido RTTI e decidiu navegar na Stack Overflow um pouco:))
Outras dicas
RTTI só irá mostrar-lhe publicados propriedades, etc. -. Não apenas as públicas
Tente o seu código com um TObject e ver o que acontece -. Se isso não está funcionando, postar seu código , porque nem todo mundo é psíquica
Você já pensou em usar o componente TXMLDocument? Ele vai olhar para o seu XML e, em seguida, criar um bom unidade de classes de Delphi que representa o arquivo XML -. Torna muito, muito fácil de ler e arquivos de gravação XML
Quanto ao problema RttiType retornando somente nulo, isso provavelmente ocorre por uma razão: em seu teste, você não instanciar a classe a qualquer momento. O compilador, porque nunca tem uma referência a esta classe (porque não é um exemplo em todos), simplesmente remove-lo a partir da informação como uma forma de optimização. Ver os dois exemplos abaixo. O comportamento é diferente quando você tem a classe instanciado em algum momento de seu código ou não.
Suponha que a seguinte classe:
type
TTest = class
public
procedure Test;
end;
e o seguinte código abaixo:
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;
até agora, TTest informações de classe não está disponível para uso por RTTI. No entanto, quando criamos em algum momento, dentro do aplicativo, em seguida, é criada uma referência para ele dentro da compilação, o que torna esta informação disponível:
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;
Neste ponto, se você usar LContext.FindType ( 'TTest') , não haverá um retorno nulo, porque o compilador mantido referência à classe. Isso explica o comportamento que você estava tendo nos seus testes.