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 protected和strict 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 private或private 成员.这个"功能"实际上是Embarcadero现在在柏林修复的编译器错误.你运气不好.
在Delphi 10.1 Berlin中删除了对类的访问private和strict 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)