【问题标题】:Delphi 2009: Is it possibly dangerous to use TList<[any interface]> with default comparator?Delphi 2009:将 TList<[any interface]> 与默认比较器一起使用是否可能很危险?
【发布时间】:2010-10-05 10:49:46
【问题描述】:

我想知道使用泛型TList&lt;T&gt; 是否有危险,其中T 是任何接口类型(IUnknown/IInterface 除外)。我大量使用接口并将它们存储在列表中。有些接口是我自己的,有些是一些COM接口提供的,所以涉及到COM。

我看到了一个潜在的问题,即检查实例是否相等,例如当我使用列表的Remove 方法时(内部需要将我提供的值与包含的值进行比较)。根据 COM 规则,您只能在将两个接口转换为 IUnknown 后比较它们是否相等。我不知道在TList&lt;T&gt; 中查找我的接口所涉及的默认比较器是否知道这一点。

用一个例子来说明我的问题:

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

上面的代码合法吗?

【问题讨论】:

    标签: delphi generics com delphi-2009 interface


    【解决方案1】:

    除非接口通过 QueryInterface() 降级为 IUnknown,否则这可能会成为您的问题,因为它可能不遵守 COM 规则。

    tkInterface 的默认 IComparer 和 IEqualityComparer 只是将指针值作为四字节整数进行比较(因此,QueryInterface 完成了返回聚合的操作)。在 Generics.Defaults 中查找 tkInterface 即可查看。

    您可以通过在构建列表时提供 IComparer 或 IEqualityComparer 自行避免此问题。

    我认为将泛型与接口结合使用不会有任何引用计数问题。

    【讨论】:

    • 感谢您提到降级到 IUnknown - 忘记这确实会导致问题!
    【解决方案2】:

    TInterfaceList 类型对你有用吗?

    这是专门为处理接口列表而设计的。

    【讨论】:

    • 我曾经使用过 TInterfaceList 但爱上了通用列表,因为它更容易使用。但是,当越来越多地使用它们时,我想到了旧的“接口引用比较”——因此有人可以澄清这一点的问题。
    猜你喜欢
    • 2010-12-28
    • 2019-07-10
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 2019-03-15
    • 1970-01-01
    • 2013-08-30
    相关资源
    最近更新 更多