如何为TList <t> </t>编写通用的FreeAll

时间:2010-11-03 06:47:27

标签: delphi generics

编写FreeAll函数的最佳方法是采用通用TList<T>并释放列表中的每个元素?

TList<T>.FreeAll不存在是有道理的,因为如果泛型类型是Record或String则没有意义。然而,如果泛型类型是一个对象,如果有某种方法可以实现FreeAll功能,那将非常方便。

我的简单尝试不能编译......

TTest1 = Class

End;

Procedure FreeAll(List : TList<TObject>);
Var
    I : Integer;
Begin
    For I := 0 To List.Count - 1 Do
        List[I].Free;
End;


Procedure Main;
Var
    List : TList<TTest1>;
    I : Integer;
Begin
    List := TList<TTest1>.Create;
    List.Add(TTest1.Create);
    List.Add(TTest1.Create);
    List.Free;

    FreeAll(List);

    List.Free;
End;

2 个答案:

答案 0 :(得分:9)

在相同的Generics.collections.pas单元中,您有TObjectList,OwnsObjects属性可能就是您要查找的内容(例如,将OwnsObject设置为true,调用Clear方法,并且所有列出的对象都已正确释放)。

或者您可以编写自己的TList(或者可能是TObjectList)后代,您可以将其作为方法添加。

答案 1 :(得分:4)

您的示例解决方案不起作用的原因是实例化泛型类型的子类型关系与类型参数的子类型关系的不变性:示例中的类型参数(TTest1和{{1}具有继承关系并不意味着实例化类型TObjectTList<TTest1>具有继承关系。很容易理解为什么会这样;考虑TList<TObject>类型的值,该值可分配给TList<TCat>类型的位置b;然后,在TList<TAnimal>引用的列表中插入TDog类型的值,即使其运行时类型为b,也不应该TList<TCat>,这样就可以了。 in。

但是,您可以编写想要编写的方法:

TDog