【问题标题】:Delphi interfaces and IList<T> (or TObjectList<T>)Delphi 接口和 IList<T>(或 TObjectList<T>)
【发布时间】:2014-03-27 05:47:33
【问题描述】:

我正在尝试实现 Spring 4 Delphi,并且只对接口而不是类进行编程。但是,当您想使用 TObjectList 时,这似乎是不可能的。

考虑以下代码:

unit Unit1;

interface

uses
  Spring.Collections,
  Spring.Collections.Lists;

type

  IMyObjParent = interface
  ['{E063AD44-B7F1-443C-B9FE-AEB7395B39DE}']
    procedure ParentDoSomething;
  end;

  IMyObjChild = interface(IMyObjParent)
  ['{E063AD44-B7F1-443C-B9FE-AEB7395B39DE}']
    procedure ChildDoSomething;
  end;

implementation

type
  TMyObjChild = class(TInterfacedObject, IMyObjChild)
  protected
    procedure ParentDoSomething;
  public
    procedure ChildDoSomething;
  end;


{ TMyObj }

procedure TMyObjChild.ChildDoSomething;
begin

end;

procedure TMyObjChild.ParentDoSomething;
begin

end;

procedure TestIt;
var
  LMyList: IList<IMyObjChild>;
begin
  TCollections.CreateObjectList<IMyObjChild>;
  //[DCC Error] Unit1.pas(53): E2511 Type parameter 'T' must be a class type
end;

end.

我知道我可以在上面的示例中将 IMyObjChild 更改为 TMyObjChild,但如果我需要在另一个单元或表单中进行更改,我该怎么做?

一旦您需要 TObjectList,就尝试只对接口进行编程似乎太难或不可能。

Grrr...有什么想法或帮助吗?

【问题讨论】:

  • 你可以使用TInterfaceList。
  • 如果您使用接口,则不需要 TObjectList,因为它对 TList 所做的只是管理它所持有的对象的生命周期。
  • 谢谢!这几天我一直在努力解决这个问题,但由于接口是引用计数,因此可以使用 TList 代替 TObjectList。
  • FWIW,看起来您的界面具有完全相同的 GUID。这可能会成为一个问题。每个接口都应该有一个不同的接口。在编辑器中使用 Shift+Ctrl+G 生成一个新的。

标签: delphi generics spring4d


【解决方案1】:

CreateObjectList 有一个泛型约束,它的类型参数是一个类:

function CreateObjectList<T: class>(...): IList<T>;

您的类型参数不符合该约束,因为它是一个接口。关于对象列表的事情是它包含对象。如果您查看Spring.Collections.Lists 中的TObjectList,您会发现它还具有其类型参数是类的通用约束。由于CreateObjectList 将创建一个TObjectList&lt;T&gt;,它必须反映类型约束。

TObjectList&lt;T&gt; 的存在理由是通过OwnsObjects 承担其成员的所有权。与同名的经典 Delphi RTL 类非常相似。当然你持有接口,所以你根本不需要这个功能。你应该打电话给CreateList。即使您通过IList&lt;T&gt; 接口引用它,您也需要一个普通的TList&lt;T&gt;

LMyList := TCollections.CreateList<IMyObjChild>;

【讨论】:

  • 太完美了,非常感谢你和 Stefan!
  • 现在看起来很明显,但我使用 TObjectList 已经很长时间了,以至于在迁移到接口时我只是假设我需要继续使用它。再次感谢,这对我来说真的很令人兴奋:-D
  • 对于习惯于旧版Contnrs.TObjectList 的开发人员来说,想要将它用于所有事情似乎很常见。如果您打算将OwnsObjects 设置为True,则只需要使用TObjectList。否则,普通的通用 TList&lt;T&gt; 很好。即使是对象。 TObjectList&lt;T&gt; 的唯一目的是拥有对象。但是开发人员已经学会使用它,因为在非通用 Delphi 中,与普通 TList 相比,它减少了转换量。
猜你喜欢
  • 1970-01-01
  • 2013-02-06
  • 1970-01-01
  • 2012-10-02
  • 2012-05-28
  • 2011-04-04
  • 1970-01-01
  • 2017-06-10
  • 1970-01-01
相关资源
最近更新 更多