如何使用 TMyRecord 中的通用子列表释放通用 TList<TMyRecord>

Posted

技术标签:

【中文标题】如何使用 TMyRecord 中的通用子列表释放通用 TList<TMyRecord>【英文标题】:How to free a generic TList<TMyRecord> with generic sub lists in TMyRecord 【发布时间】:2016-05-31 14:32:02 【问题描述】:

在 Windows 下的 Delphi 10 Berlin 中,我有以下关于释放通用列表的问题:

我有以下记录/列表结构:

type
  TMyRecord=record
    Value1: Real;
    SubList1: TList<Integer>;
    SubList2: TList<Real>;
  end;

  TMyListOfRecords=TList<TMyRecord>;

我想使用以下代码释放结构:

var
  i: Integer;
  AMyListOfRecords: TMyListOfRecords;
begin
  //other code

  //free AMyListOfRecords and all its content
  for i:=0 to AMyListOfRecords.Count-1 do
  begin
    AMyListOfRecords[i].SubList1.Free;
    AMyListOfRecords[i].SubList2.Free;
  end;
  AMyListOfRecords.Free;
end;

这似乎有效。但我想知道是否有更简单或更优雅的解决方案?

【问题讨论】:

如果您可以使用 DeHL,那么您可以只使用 IList,它将像任何其他接口对象一样自动管理。 否则你可以在 IList 上实现你自己的包装器而不是 TList 并使用 TInterfacedObject。 你的代码对我来说很好 我推荐使用 Spring4Ds 接口的泛型集合——DeHL 已经死了。 @StefanGlienke 感谢提及.. 我只是不记得因为我们还没有使用 Spring4D,所以我不记得它在哪里 :) 【参考方案1】:

您可以将记录类型转换为类 - 开销可以忽略不计,因为记录已经包含子对象。在此类析构函数中释放子对象,并使用

 TMyListOfClasses = TObjectList<TMyClass>;

OwnsObjects = True

在这种情况下,您只需要

AMyListOfClasses.Free;

【讨论】:

它是维护一个单独的要销毁的拥有对象列表,还是使用 RTTI 来销毁? @Michael TObjectList 只是一个对象列表,它会破坏其所有元素(如果OwnsObjects),不需要单独的列表或RTTI 是的,我是老派。我更喜欢使用析构函数,因为有时你没有拥有的选项而我忘记了。【参考方案2】:

您可以为子项定义接口列表,例如:

type
  TMyRecord=record
    Value1: Real;
    SubList1: IList<Integer>;
    SubList2: IList<Real>;
  end;

  TMyListOfRecords=TList<TMyRecord>;

IList 是这样的:

type
  IList<T> = interface
    function Add(const AValue: T): Integer;
    function Remove(AValue: T): Integer;
  end;

你在哪里实现它:

  TIntfList<T> = class(TInterfacedObject, IList<T>)
  private
    FList: TList<T>;
    function Add(const AValue: T): Integer;
    function Remove(AValue: T): Integer;

    constructor Create;
    destructor Destroy; override;
  end;

 TIntfList<T> 

function TIntfList<T>.Add(const AValue: T): Integer;
begin
  Result := FList.Add(AValue);
end;

constructor TIntfList<T>.Create;
begin
  FList := TList<T>.Create;
end;

destructor TIntfList<T>.Destroy;
begin
  FList.Free;
  inherited;
end;

function TIntfList<T>.Remove(AValue: T): Integer;
begin
  Result := FList.Remove(AValue);
end;

之后,您可以使用 TIntfList.Create 分配记录的字段,它们将与您的记录一起自动释放。

【讨论】:

以上是关于如何使用 TMyRecord 中的通用子列表释放通用 TList<TMyRecord>的主要内容,如果未能解决你的问题,请参考以下文章

如何获取通用java树中所有祖先的列表

如何通过从数据库中获取值来制作可靠的下拉列表

如何强制通用应用程序释放内存?

如何释放子视图控制器的内存

SonarQube:(改为获取特定异常子类型的列表)

如何一次性删除通用列表中的所有空元素?