And*_*rew 10 delphi oop private private-members
我需要修复第三方组件.该组件的类具有私有变量,其后代主动使用它:
TThirdPartyComponentBase = class
private
FSomeVar: Integer;
public
...
end;
TThirdPartyComponent = class (TThirdPartyComponentBase)
protected
procedure Foo; virtual;
end;
procedure TThirdPartyComponent.Foo;
begin
FSomeVar := 1; // ACCESSING PRIVATE FIELD!
end;
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为两个类都在同一个单元中,因此它们有点像"朋友".
但是,如果我尝试在新单元中创建一个新类
TMyFixedComponent = class (TThirdPartyComponent)
procedure Foo; override;
end;
Run Code Online (Sandbox Code Playgroud)
我不能再访问FSomeVar,但我需要将它用于我的修复.我真的不想在我的代码中重现所有基类树.
如果可能的话,你能否建议一些快速破解访问该私有字段而不更改原始组件的单元?
LU *_* RD 18
通过使用class helpers它可以从派生类中完成对基类的私有部分的访问,而不会失去类型安全性.
只需在另一个单元中添加这些声明:
Uses YourThirdPartyComponent;
type
// A helper to the base class to expose FSomeVar
TMyBaseHelper = class helper for TThirdPartyComponentBase
private
procedure SetSomeVar( value : integer);
function GetSomeVar: integer;
public
property SomeVar:integer read GetSomeVar write SetSomeVar;
end;
TMyFixedComponent = class helper for TThirdPartyComponent
protected
procedure Foo;
end;
procedure TMyFixedComponent.Foo;
begin
// Cast to base class and by the class helper TMyBaseHelper the access is resolved
TThirdPartyComponentBase(Self).SomeVar := 1;
end;
function TMyBaseHelper.GetSomeVar: integer;
begin
Result := Self.FSomeVar; // ACCESSING PRIVATE FIELD!
end;
procedure TMyBaseHelper.SetSomeVar(value: integer);
begin
Self.FSomeVar := value; // ACCESSING PRIVATE FIELD!
end;
// Testing
var
TSV: TThirdPartyComponent;
begin
TSV := TThirdPartyComponent.Create;
try
TSV.Foo;
WriteLn(IntToStr(TSV.SomeVar)); // Writes 1
finally
TSV.Free;
end;
end.
Run Code Online (Sandbox Code Playgroud)
从代码中的注释可以看出,FSomeVar是由类中的类助手公开的TThirdPartyComponentBase.另一个用于TThirdPartyComponent实现Foo过程的类助手.在那里,通过对SomeVar基类的类型转换来访问基类助手的属性.
您必须使用hack来访问不同单元中任何类(包括基类)中的私有字段.在您的情况下,在您的单位中定义:
type
__TThirdPartyComponentBase = class
private
FSomeVar: Integer;
end;
Run Code Online (Sandbox Code Playgroud)
然后获取访问权限:
__TThirdPartyComponentBase(Self).FSomeVar := 123;
Run Code Online (Sandbox Code Playgroud)
当然,这很危险,因为您需要控制基类中的更改.因为如果字段布局将被更改而您将错过这一事实,那么上述方法将导致失败,AV等.
| 归档时间: |
|
| 查看次数: |
5182 次 |
| 最近记录: |