Delphi RTTI麻烦:GetPropInfo在{$ METHODINFO ON}上返回nil吗?

Delphi RTTI trouble: GetPropInfo returns nil with {$METHODINFO ON}?

即使使用正确的{$ METHODINFO}指令声明了给定的类,GetPropInfo是否有可能返回nil。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  type
  ...
  ...
    {$METHODINFO ON}
    TMyClass = class
    private
      fField: integer;
    published
      property Field: integer read fField write fField;
    end;
    {$METHODINFO OFF}
  ...
  ...
  procedure TestRTTI;
  begin
    assert(assigned(GetPropInfo(TMyClass, 'Field')), 'WTF! No RTTI found!');
  end;

Gotcha!似乎问题隐藏在我忽略的前向声明中。不知道那个偷偷摸摸的功能。

似乎编译器仅考虑是否使用类的第一个声明来生成RTTI,因此,如果您有这样的前向声明...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  type
    TMyClass = class;  
    ...    
    ...
    {$METHODINFO ON}
    TMyClass = class
    private
      fField: integer;
    published
      property Field: integer read fField write fField;
    end;
    {$METHODINFO OFF}  
    ...  
    ...  
    procedure TestRTTI;  
    begin
      assert(assigned(GetPropInfo(TMyClass, 'Field')), 'WTF! No RTTI found!');  
    end;

...您将得到断言错误。因此,为了正确设置RTTI,需要打开{$ METHODINFO}指令以进行前向声明,如此处所示....

1
2
3
4
5
6
7
8
9
10
11
12
13
  type
    {$METHODINFO ON}
    TMyClass = class;  
    {$METHODINFO OFF}  
    ...    
    ...
    TMyClass = class
    private
      fField: integer;
    published
      property Field: integer read fField write fField;
    end;
    ...


很高兴您找到了解决方案。 $TypeInfo指令也是如此。 Delphi 7帮助说:

Note that if a class is forward declared, the first declaration of the class must be declared with the $M switch.

P.S .: $M+/- = $TypeInfo On/Off