如何使用类助手访问类的严格私有成员?

Joh*_*ica 28 delphi class-helpers

这是一个后续问题:如何隐藏对象的受保护过程?
(我对整个班助手概念有点模糊)

假设我有一个类:

type 
TShy = class(TObject) 
strict private
  procedure TopSecret;
private
  procedure DirtyLaundry;  
protected 
  procedure ResistantToChange;
end; 
Run Code Online (Sandbox Code Playgroud)

我知道如果我通过在同一单元中添加一个后代类来获得源代码,我可以访问私有方法.

我有两个问题:
- 如何使用班助手访问strict private会员?
- 我可以在一个单独的单元中使用类助手来访问(严格)私有成员吗?

Rem*_*eau 37

最多,包括Delphi 10.0 Seattle,您可以使用类助手来访问strict protectedstrict private成员,如下所示:

unit Shy;

interface

type
  TShy = class(TObject)
  strict private
    procedure TopSecret;
  private
    procedure DirtyLaundry;
  protected
    procedure ResistantToChange;
  end;
Run Code Online (Sandbox Code Playgroud)

unit NotShy;

interface

uses
  Shy;

type
  TNotShy = class helper for TShy
  public
    procedure LetMeIn;
  end;

implementation

procedure TNotShy.LetMeIn;
begin
  Self.TopSecret;
  Self.DirtyLaundry;
  Self.ResistantToChange;
end;

end.
Run Code Online (Sandbox Code Playgroud)

uses
  ..., Shy, NotShy;

procedure TestShy;
var
  Shy: TShy;
begin
  Shy := TShy.Create;
  Shy.LetMeIn;
  Shy.Free;
end;
Run Code Online (Sandbox Code Playgroud)

但是,从Delphi 10.1柏林开始,这已不再适用!级助手将不再能访问strict protected,strict privateprivate 成员.这个"功能"实际上是Embarcadero现在在柏林修复的编译器错误.你运气不好.

  • 请参阅[RSB-1146修复"类助手允许跨单位私人违规"破坏现有代码](https://quality.embarcadero.com/browse/RSB-1146)和Marco对[RSB-1254无法访问的评论]帮助中的私人领域](https://quality.embarcadero.com/browse/RSB-1254),例如"*[帮助私人访问权限]"作为错误提交并且是理所当然的.研发人员并不知道我们考虑过把这个bug打开,但决定反对.这太过于根本问题*". (4认同)
  • 我测试了我在XE2中发布的内容,一切正常. (3认同)
  • 这在Delphi 10.1 Berlin中不再适用(对于私有成员),因为它已被归类为编译器中的错误并已修复. (3认同)
  • JFTR:在D2007中,`Self.DirtyLaundry;`和`Self.ResistantToChange;`行不会编译而`Self.TopSecret;`**做**.即你可以访问`strict private`成员,但不能访问`private`或`protected`成员.:-D (2认同)

LU *_* RD 7

在Delphi 10.1 Berlin中删除了对类的访问privatestrict private成员class helpers.请参阅关闭类助手私人访问漏洞.

但仍有一个开放的漏洞:

unit Shy;

interface

type
  TShy = class(TObject)
  strict private
    procedure TopSecret;
  private
    procedure DirtyLaundry;
  protected
    procedure ResistantToChange;
  end;

implementation

procedure TShy.DirtyLaundry;
begin
  WriteLn('DirtyLaundry');
end;

procedure TShy.ResistantToChange;
begin
  WriteLn('ResistantToChange');
end;

procedure TShy.TopSecret;
begin
  WriteLn('TopSecret');
end;

end.
Run Code Online (Sandbox Code Playgroud)
Program TestClassHelpers;

{$APPTYPE CONSOLE}

Uses
  Shy;

type
  TNotShy = class helper for TShy
  public
    procedure LetMeIn;
  end;

procedure TNotShy.LetMeIn;
var
  P : procedure of object;
begin
  TMethod(P).Code := @TShy.TopSecret;
  TMethod(P).Data := Self;
  P; // Call TopSecret
  TMethod(P).Code := @TShy.DirtyLaundry;
  TMethod(P).Data := Self;
  P; // Call DirtyLaundry;
  Self.ResistantToChange;  // Protected access works without problems
end;

var
  myObj: TShy;
begin
  myObj := TShy.Create;
  try
    myObj.LetMeIn;
    ReadLn;
  finally
    myObj.Free;
  end;
end.
Run Code Online (Sandbox Code Playgroud)

  • 我担心这不会完全取代旧的"功能",因为它只能让你访问方法,而不是字段.在Delphi 10.1 Berlin之前,我们还可以访问该类的私有字段. (3认同)