views:

638

answers:

2

Hello everyone,

I am wondering if the usage of a generic TList<T> where T is any interface type (except IUnknown/IInterface) might be dangerous. I am heavily using interfaces and store them in lists. Some interfaces are my own, some are provided by some COM-interfaces, so COM is involved.

I see a potential problem where checks for instance-equality happens, e.g. when I use the Remove method of the list (which internally needs to compare my provided value to the contained values). According to COM-rules you can only compare two interfaces for equality after casting them to IUnknown. I don't know if the default comparator involved in finding my interface in the TList<T> is aware of that.

To illustrate my question with an example:

var
  list:TList<IMyInterface>;
  intf:IMyInterface;
begin
  ...
  list:=TList<IMyInterface>.Create;
  list.Add(intf);
  ...
  list.Remove(intf);
end;

Is the above code legitimate?

+1  A: 

Would the TInterfaceList type work for you?

This is designed specifically to work with a list of interfaces.

Toby Allen
I used to use TInterfaceList but fell in love with the generic lists because its much easier to work with them. But while using them more and more the old "comparing of interface references"-thing came to my mind - hence the question if somebody can clarify this.
Heinrich Ulbricht
+2  A: 

Unless the interface is downgraded to IUnknown via QueryInterface() then there is some potential for this to be an issue for you as it may not have respected the COM rules.

The default IComparer and IEqualityComparer for tkInterface simply compares the pointer values as four byte integers (so, there is on QueryInterface done to get back to the aggregate). Look for tkInterface in Generics.Defaults to see.

You can avoid this problem yourself by supplying a IComparer or IEqualityComparer when you construct the list.

I do not believe there are any reference counting issues from using generics with interfaces.

Ryan VanIderstine
Thanks for mentioning the downgrading to IUnknown - forgetting this can indeed cause problems!
Heinrich Ulbricht