Delphi接口和IList <t>(或TObjectList <t>)</t> </t>

时间:2014-03-27 05:47:33

标签: delphi generics spring4d

我正在尝试实现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 ......有什么想法或帮助吗?

1 个答案:

答案 0 :(得分:4)

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

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

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

TObjectList<T>的存在理由是通过OwnsObjects承担其成员的所有权。与同名的经典Delphi RTL类的方式大致相同。当然,您持有接口,因此您根本不需要此功能。你应该拨打CreateList。即使您通过TList<T>界面引用它,也可以使用普通IList<T>

LMyList := TCollections.CreateList<IMyObjChild>;