Delphi RTTI问题:{$METHODINFO ON}时GetPropInfo返回nil?

5
有没有可能 GetPropInfo 返回 nil,即使给定的类使用正确的 {$METHODINFO} 指令声明?
  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;
2个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
5

注意!看起来问题隐藏在我忽略的前向声明中。不知道那个狡猾的特性。

似乎编译器只考虑类的第一个声明来生成RTTI,因此如果你有这样的前向声明...

  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;

如果你没有打开{$METHODINFO}指令并进行前向声明,就会得到断言错误。因此,为了正确获取RTTI,需要在前向声明中打开{$METHODINFO}指令,如下所示...

  type 
    {$METHODINFO ON}
    TMyClass = class;   
    {$METHODINFO OFF}   
    ...    
    ...
    TMyClass = class
    private
      fField: integer;
    published
      property Field: integer read fField write fField;
    end;
    ...   

1
我已经遇到过这个“特性”了。 顺便说一下,不需要打开完整的{$METHODINFO ON},只需使用{$TYPEINFO ON}或{$M+}即可。 - Ondrej Kelle
1
需要注意的是,在Delphi 2009中,编译器会自动将{M+}添加到任何带有“published”部分的类中,因此这个问题不再存在。 - Mason Wheeler

1
我很高兴你找到了解决方案。这与$TypeInfo指令是一样的。Delphi 7帮助文档中写道:

请注意,如果一个类被前向声明,那么该类的第一个声明必须使用$M开关声明。

附注:$M+/- = $TypeInfo On/Off

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,