Возможен ли универсальный TInterfaceList для Delphi? - PullRequest
7 голосов
/ 09 февраля 2010

В Delphi 2010 я определил универсальный TInterfaceList следующим образом:

type

TInterfaceList<I: IInterface> = class(TInterfaceList)
  function GetI(index: Integer): I;
  procedure PutI(index: Integer; const Item: I);
  property Items[index: Integer]: I read GetI write PutI; default;
end;

implementation

function TInterfaceList<I>.GetI(index: Integer): I;
begin
  result := I(inherited Get(Index));
end;

procedure TInterfaceList<I>.PutI(index: Integer; const Item: I);
begin
  inherited Add(Item);
end;

У меня еще не было проблем, но есть ли что-то рискованное в этом? Можно ли добавить в него перечислитель, чтобы позволить циклам ..in работать с ним? Если в этом нет ничего плохого, мне интересно, почему нечто подобное еще не определено в RTL.

1 Ответ

13 голосов
/ 09 февраля 2010

Не используйте TInterfaceList в качестве базового класса.

Если вы выполняете однопоточную работу, вы можете просто использовать TList<I: IInterface>. Производительность была бы лучше, поскольку нет внутренней блокировки.

Если вы выполняете многопоточную работу, открытый интерфейс TInterfaceList не подходит, как и концепция перечислителей, поскольку они реализованы в VCL. Для обсуждения лучшего API для безопасной итерации по коллекции вещей смотрите этот пост .

Если вы делитесь списком интерфейсов между потоками, вы должны заблокировать его как можно короче. Хороший способ сделать это - реализовать потокобезопасный метод, который возвращает массив интерфейсов вызывающему потоку, который затем можно безопасно перебирать, не сохраняя исходный список заблокированным.

...