通过RTTI调用受保护的方法(构造函数)

san*_*oIT 5 delphi delphi-xe2

我正在使用XE-2.

是否可以使用RTTI调用受保护的方法(构造函数)?

我在网上搜索但没有找到任何确凿的答案.据我所知,在XE之前,只有已发布的方法/属性可用.我对私有字段有写访问权限,所以我希望能够调用受保护的方法.

只要构造函数是公共的,以下代码就可以工作.

function GetDefaultConstructor(aRttiType: TRttiType): TRttiMethod;
var
   Method: TRttiMethod;
begin
   for Method in aRttiType.GetMethods('Create') do
   begin
      if (Method.IsConstructor) and (length(Method.GetParameters) = 0) and (Method.Parent = aRttiType) then
         Exit(Method);
   end;
   Result := nil;
end;
Run Code Online (Sandbox Code Playgroud)

RRU*_*RUZ 11

默认情况下,RTTI不包含有关受保护方法或构造函数的信息,但您可以使用RTTI EXPLICITDirective包含受保护方法的RTTI信息,如此.

  {$RTTI EXPLICIT METHODS([vcPrivate, vcProtected, vcPublic, vcPublished])}
  TFoo= class
  protected
    constructor Create;
  end;
Run Code Online (Sandbox Code Playgroud)


Dav*_*nan 9

RTTI信息增加了可执行文件的大小.因此,设计人员为开发人员提供了一种方法,用于指定将RTTI信息链接到可执行文件的程度.

默认情况下,没有链接受保护方法的RTTI.因此,您必须指定要添加此RTTI.例如,这个程序

{$APPTYPE CONSOLE}

uses
  System.TypInfo, System.Rtti;

type
  TMyClass = class
  protected
    constructor Create;
  end;

constructor TMyClass.Create;
begin
end;

var
  ctx: TRttiContext;
  method: TRttiMethod;

begin
  for method in ctx.GetType(TMyClass).GetMethods do
    if method.Visibility=mvProtected then
      Writeln(method.Name);
end.
Run Code Online (Sandbox Code Playgroud)

没有输出.但是,这个计划

{$APPTYPE CONSOLE}

uses
  System.TypInfo, System.Rtti;

type
  {$RTTI EXPLICIT METHODS([vcProtected])}
  TMyClass = class
  protected
    constructor Create;
  end;

constructor TMyClass.Create;
begin
end;

var
  ctx: TRttiContext;
  method: TRttiMethod;

begin
  for method in ctx.GetType(TMyClass).GetMethods do
    if method.Visibility=mvProtected then
      Writeln(method.Name);
end.
Run Code Online (Sandbox Code Playgroud)

输出

Create

有关更多信息,请参阅以下文档主题: