考虑这个简单的代码
{$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.类变量不是被调查对象的成员.