views:

215

answers:

1

In Delphi 2010, I have defined a generic TInterfaceList as follows:

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;

I haven't had any problems yet, but is there anything inherently risky about doing this? Would it be possible to add an enumerator to it to allow for..in loops to work on it? If there's nothing wrong with it, I wonder why something similar isn't already defined in the RTL.

+8  A: 

Do not use TInterfaceList as a base class.

If you do single-threaded work you could just use a TList<I: IInterface> instead. Performance would be better, as there is no internal locking.

If you do multi-threaded work the public interface of TInterfaceList is unsuitable, as is the concept of enumerators as they are implemented in the VCL. For a discussion of a better API to iterate safely over a collection of things see this blog post.

If you share your list of interfaces between threads you should lock it as short as possible. A good way to do that is to implement a thread-safe method that returns an array of interfaces to the calling thread, which can then be safely iterated over, without keeping the original list locked.

mghie