Posted at

[小ネタ]疑似フレンドの別の解法


疑似フレンド

以前、こんな話を書きました。

Delphi の疑似フレンド

要約すると Unit Friend を使って別の所から Protected にアクセスできるよ、という話です。


TFoo宣言

unit Foo;

interface

type
TFoo = class
protected
procedure Bar; ///// ← 同じ Unit 内か継承先からしかアクセス出来ないが…
end;



別の場所からアクセス

unit Bar;

interface

type
TOpenFoo = class(TFoo) end; ///// ← こんな風にダミーで継承すると…

implementation

procedure Baz;
begin
var Foo := TFoo.Create;
TOpenFoo(Foo).Bar; ////// ← TOpenFoo と同じ Unit 内なので Protected にアクセスできる!
end;

end.



もうひとつの冴えた?やりかた

疑似フレンドは毎回キャストしないと行けないしエレガントじゃないなーと思っていたんですよ。

で、こんな風に Class Helper 使ってみたら割とエレガントじゃないですか?

type

TFooHelper = class helper for TFoo
public
procedure BazCaller;
end;

procedure TFooHelper.BazCaller;
begin
Baz;
end;

最近だと、こんな感じで TScrollBox が隠している ScrollBar にアクセスするために使いました。

こういう用途だと、TOpen でキャストするよりエレガントに書けます。

type

TScrollBoxHelper = class helper for TScrollBox
private
function GetHorzScrollBar: TScrollBar;
function GetVertScrollBar: TScrollBar;
public
property HorzScrollBar: TScrollBar read GetHorzScrollBar;
property VertScrollBar: TScrollBar read GetVertScrollBar;
end;

function TScrollBoxHelper.GetHorzScrollBar: TScrollBar;
begin
Result := HScrollBar;
end;

function TScrollBoxHelper.GetVertScrollBar: TScrollBar;
begin
Result := VScrollBar;
end;


まとめ

Class Helper を使う方法はコード量が増えるので時と場合しだいですね。

でも、こんなやり方があるよって知ってるとごく稀にイイかもしれません。