Delphi で Generics で Interface なリスト IList
Delphi の Generics なリストを interface で作成したい
検索結果のリストを渡すとき等、リストそのものがインターフェイスじゃないので、受け取り側で TList<IHoge> の中身だけ、別のリストへコピーとかになってしまうわけです
そこで IList<IHoge> みたいなのがあれば、リストそのものを代入すれば参照カウンタが上がって安全にかつ迅速に引き渡せるハズ
調べたら 型が IInterface に制約される System.Classes.IInterfaceList とかいうのがあるので、THoge(List.Items[I]) のように取り出し時にキャストしてやれば使えます
※リストは参照なので、受け取り側で変更すると受け渡し側へも影響ありです
IInterfaceList で OKな方はここまでで完了
Delphi で interface のベースクラスは 「TInterfacedObject を継承してないと参照カウンタは実装されません」とかいう制約がある
TList との 多重継承はNGなので、TInterfacedObjectを継承したクラスの中で TList 型の変数を持って、出入り口を作り直せとかいう事らしい(ChatGPTの回答もそれだった)
先程の IInterfaceList も private に FList: TThreadList<IInterface> とかいうリストを持ってました
それって Count やら Items やら(無駄に)再定義して、使っていくうちにアレが足りないとかなりそうじゃないですか...
ということで、TList をそのまま Itemプロパティとして外部に出してやるという手抜き実装
type
IListGen<T> = interface
function _GetList: TList<T>;
property Item: TList<T> read _GetList;
end;
TListGen<T> = class(TInterfacedObject, IListGen<T>)
private
FList: TList<T>;
function _GetList: TList<T>;
public
constructor Create;
destructor Destroy; override;
property Item: TList<T> read _GetList; // ココ
end;
implementation
{ TListGen<T> }
constructor TListGen<T>.Create;
begin
FList := TList<T>.Create;
end;
destructor TListGen<T>.Destroy;
begin
FList.Free;
inherited;
end;
function TListGen<T>._GetList: TList<T>;
begin
Exit(FList);
end;
こんな感じで Item という記述は増えますが、Generic で interface なリストが使えます
var List: IListGen<string>;
begin
List := TListGen<string>.Create;
List.Item.Add('foo');
List.Item.Items[0] // 'foo'
end;
コメント