delphi – 使用RTTI访问严格的私有字段

考虑这个简单的代码
{$APPTYPE CONSOLE}

uses
  Rtti,SysUtils;

type
  {$M+}
  TFoo = class
  strict private
    class var Field1 : Integer;
    field2 :  Integer;
  private
    field3 :  Integer;
    class var Field4 : Integer;
  end;


Var
    ctx : TRttiContext;
    f   : TRttiField;
begin
  try
    ctx:=TRttiContext.Create;

    for f in ctx.GetType(TFoo).GetFields do
     Writeln(f.Name);


    Writeln('Done');
    readln;
  except
    on E: Exception do
      Writeln(E.ClassName,': ',E.Message);
  end;
end.

运行此时,仅列出field3.似乎哪个RTTI不支持严格私有或类var的字段,所以问题是可以使用Rtti或其他方法访问delphi类的严格私有字段?我阅读了RTTI.TRttiType.GetFields方法的文档,但确实提到了这些限制,是否存在提及此类限制的任何文章文章

解决方法

我现在无法尝试,但您似乎需要的可能是GetDeclaredFields而不是GetFields.这应该给出类的所有(实例)字段,但不能给出祖先类的字段.如果你也需要这些,你必须递归地继承继承链.

正如我所说,我现在无法尝试,所以你必须亲自看看它是否允许你访问严格的私人领域.

更新

请注意,在您的TFoo声明中,即使您可能没有意图,Field1和Field2都是类变量

只需重新格式化你的声明,你就会明白我的意思:

TFoo = class
  strict private
    class var
      Field1: Integer;
      Field2: Integer;
  private
    // etc...

类var之后的所有内容都是类变量,直到编译器遇到var,strict,private,protected等.试试这个,你也会看到Field2被写入:

TFoo = class
  strict private
    class var 
      Field1: Integer;
    var 
      Field2: Integer;
    // etc...

或者尝试:

TFoo = class
  strict private
    Field2: Integer;
    class var 
      Field1: Integer;
    // etc...

这意味着GetFields和GetDeclaredFields对严格的私有字段没有任何问题.他们只是不返​​回类变量.这是有道理的,IMO.类变量不是被调查对象的成员.

相关文章

 从网上看到《Delphi API HOOK完全说明》这篇文章,基本上都...
  从网上看到《Delphi API HOOK完全说明》这篇文章,基本上...
ffmpeg 是一套强大的开源的多媒体库 一般都是用 c/c+&#x...
32位CPU所含有的寄存器有:4个数据寄存器(EAX、EBX、ECX和ED...
1 mov dst, src dst是目的操作数,src是源操作数,指令实现的...