2014-03-27 45 views
3

我想实现Spring 4德尔福和只有程序接口,而不是类。然而,当你想使用TObjectList时,这似乎是不可能的。德尔福接口和IList <T>(或TObjectList <T>)

考虑下面的代码:

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 ...任何想法或帮助?

+3

您可以使用TInterfaceList。 –

+2

如果使用接口,则不需要TObjectList,因为它在TList上的所有操作都管理它所持有的对象的生命周期。 –

+0

谢谢!我已经为此苦苦挣扎了好几天,但由于接口是引用计数,所以TList可以用来代替TObjectList。 –

回答

4

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

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

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

TObjectList<T>的存在理由是通过OwnsObjects承担其成员的所有权。与经典的同名Delphi RTL类很像。当然你拥有接口,所以你根本不需要这个功能。您应该拨打CreateList。即使您通过IList<T>界面提及它,也可以使用简单的TList<T>

LMyList := TCollections.CreateList<IMyObjChild>; 
+0

非常完美,非常感谢你和Stefan! –

+0

现在看起来如此明显,但我一直在使用TObjectList很长时间,当转移到接口时,我只是假设我需要继续使用它。再次感谢,对我来说这实际上是相当令人兴奋的:-D –

+1

对于我来说,用于传统'Contnrs.TObjectList'的开发者想要将它用于一切,这似乎很常见。如果您打算将“OwnsObjects”设置为“True”,则只需要使用'TObjectList'。否则,普通的'TList '很好。即使是对象。 'TObjectList '的唯一目的是为了拥有对象。但开发人员已经学会了使用它,因为在非泛型Delphi中,与普通的'TList'相比,它减少了投射量。 –