2008-10-03 90 views
2

我想在Delphi中解析对象到XML,所以我读了关于调用对象的ClassInfo方法来获取其RTTI信息。德尔福在对象RTTI

事情是,这显然只适用于TPersistent对象。否则,我必须专门为编译器的源代码添加一个编译器指令{$ M +}来生成RTTI信息。

所以我很高兴地添加了指令,发现即使它从ClassInfo调用中返回了一些东西(它用于返回nil),现在我无法从中检索类的属性,字段或方法。就像它创建了空的对象。

任何想法我在这里想念什么?谢谢!

回答

7

您是否已将这些属性和方法放入published部分?

除此之外,'classic'RTTI($ TYPEINFO ON)只会为您提供有关属性的信息,而不是方法。你需要'扩展'RTTI($ METHODINFO ON)。

很好的出发点扩展RTTI:David Glassborow on extended RTTI

(谁也不会相信眼前这个分我写完使用扩展RTTI一些代码,并决定浏览堆栈溢出的一点:))

+0

谢谢,那必须是问题所在。我把这些物业放在公众面前,而不是公布的部分。 我必须等待星期一去尝试,因为我在工作时做了Delphy,而且我已经在周末回家了。 – 2008-10-03 20:13:34

3

RTTI只会告诉你已发布属性等。 - 不只是公开的。

用TObject试试你的代码,看看会发生什么 - 如果这不起作用,发布你的代码因为不是每个人都是精神病。

+0

这就是问题所在,我的房产只是公开的,没有公布。 周一我回到工作时会试试。谢谢! – 2008-10-03 20:14:44

+2

delphi中的经典RTTI显示PUBLISHED属性,“new extended RTTI”实际上可以看到所有内容,但需要最新的Delphi版本(2010/XE或更高版本)。 – 2011-07-01 13:52:40

3

有无你考虑过使用TXMLDocument组件?它会查看你的XML,然后创建一个很好的代表你的XML文件的Delphi类的单元 - 使它真的很容易读写XML文件。

0

至于只返回nil的RttiType问题,这可能是因为一个原因:在你的测试中,你没有在任何时候实例化类。编译器,因为它从来没有对这个类的引用(因为它根本不是一个实例),只是将它从信息中作为一种优化形式移除。看下面的两个例子。当你在你的代码中的某个点实例化类时,行为是不同的。

假设下面的类:

type 
    TTest = class 
    public 
    procedure Test; 
    end; 

和下面的下面的代码:

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; 

到目前为止,t检验类的信息是不能供RTTI使用。然而,当我们在某个点上创建,在应用程序中,然后引用为它创建了编译,这使得提供这些信息中:

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; 

在这一点上,如果你使用LContext.FindType(” TTest'),不会有零返回,因为编译器会一直引用该类。这解释了您在测试中的行为。