哪些列表可以作为临时列表?

Hei*_*cht 7 delphi list delphi-2009

处理列表仅用作临时容器的项目列表时- 您建议我使用哪些列表类型?

一世

  • 不想手动销毁列表
  • 想使用内置列表类型(没有框架,库,......)
  • 想要仿制药

能够在不造成泄漏的情况下实现这一目标:

function GetListWithItems: ISomeList;
begin
  Result := TSomeList.Create;
  // add items to list
end;

var
  Item: TSomeType;
begin
  for Item in GetListWithItems do
  begin
    // do something
  end;
end;
Run Code Online (Sandbox Code Playgroud)

我有什么选择?这是关于德尔福2009年,但为了知识,请提及2010年以上是否有这方面的新内容.

gab*_*abr 6

一个(某种程度上丑陋)的解决方法是创建一个'autodestroy'接口以及列表.它必须具有相同的范围,以便在释放接口时,您的列表也会被销毁.

type
  IAutoDestroyObject = interface
  end;

  TAutoDestroyObject = class(TInterfacedObject, IAutoDestroyObject)
  strict private
    FValue: TObject;
  public
    constructor Create(obj: TObject);
    destructor  Destroy; override;
  end;

constructor TAutoDestroyObject.Create(obj: TObject);
begin
  inherited Create;
  FValue := obj;
end; 

destructor TAutoDestroyObject.Destroy;
begin
  FreeAndNil(FValue);
  inherited;
end;

function CreateAutoDestroyObject(obj: TObject): IAutoDestroyObject;
begin
  Result := TAutoDestroyObject.Create(obj);
end; 

FList := TObjectList.Create;
FListAutoDestroy := CreateAutoDestroyObject(FList);
Run Code Online (Sandbox Code Playgroud)

您的使用示例也变得更加复杂.

type
  TSomeListWrap = record
    List: TSomeList;
    AutoDestroy: IAutoDestroyObject;
  end;

function GetListWithItems: TSomeListWrap;
begin
  Result.List := TSomeList.Create;
  Result.AutoDestroy := CreateAutoDestroyObject(Result.List);
  // add items to list
end;

var
  Item: TSomeItem;
begin
  for Item in GetListWithItems.List do
  begin
    // do something
  end;
end;
Run Code Online (Sandbox Code Playgroud)

  • @ArnaudBouchez它运作得很好.GetListWithItems的结果超出了围绕for..in循环的begin..end的'end'部分的范围. (2认同)

iam*_*osy 5

巴里·凯利的博客文章的启发在这里,你可以实现你的目的是这样的智能指针:

unit Unit80;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Generics.Collections;

type
  TMyList =class( TList<Integer>)
  public
    destructor Destroy; override;
  end;

  TLifetimeWatcher = class(TInterfacedObject)
  private
    FWhenDone: TProc;
  public
    constructor Create(const AWhenDone: TProc);
    destructor Destroy; override;
  end;

  TSmartPointer<T: class> = record
  strict private
    FValue: T;
    FLifetime: IInterface;
  public
    constructor Create(const AValue: T); overload;
    class operator Implicit(const AValue: T): TSmartPointer<T>;
    property Value: T read FValue;
  end;

  TForm80 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    function getList : TSmartPointer<TMyList>;
    { Public declarations }
  end;


var
  Form80: TForm80;

implementation


{$R *.dfm}



{ TLifetimeWatcher }

constructor TLifetimeWatcher.Create(const AWhenDone: TProc);
begin
  FWhenDone := AWhenDone;
end;

destructor TLifetimeWatcher.Destroy;
begin
  if Assigned(FWhenDone) then
    FWhenDone;
  inherited;
end;

{ TSmartPointer<T> }

constructor TSmartPointer<T>.Create(const AValue: T);
begin
  FValue := AValue;
  FLifetime := TLifetimeWatcher.Create(procedure
  begin
    AValue.Free;
  end);
end;

class operator TSmartPointer<T>.Implicit(const AValue: T): TSmartPointer<T>;
begin
  Result := TSmartPointer<T>.Create(AValue);
end;

procedure TForm80.Button1Click(Sender: TObject);
 var i: Integer;
begin
  for I in getList.Value do
   Memo1.Lines.Add(IntToStr(i));

end;

{ TMyList }

destructor TMyList.Destroy;
begin
  ShowMessage('Kaputt');
  inherited;
end;

function TForm80.getList: TSmartPointer<TMyList>;
var
  x: TSmartPointer<TMyList>;
begin
  x := TMyList.Create;
  Result := x;
  with Result.Value do
  begin
    Add(1);
    Add(2);
    Add(3);
  end;
end;

end.
Run Code Online (Sandbox Code Playgroud)

查看getList和Button1click以查看其用法.


Rem*_*eau 3

标准列表类,如TListTObjectListTInterfaceList等,不实现自动生命周期,因此您必须在使用完它们后手动释放它们。如果您想要一个可通过接口访问的列表类,您必须自己实现,例如:

type
  IListIntf = interface
    ...
  end;

  TListImpl = class(TInterfacedObject, IListIntf)
  private
    FList: TList;
    ...
  public
    constructor Create; override;
    destructor Destroy; override;
    ...
  end;

constructor TListImpl.Create;
begin
  inherited;
  FList := TList.Create;
end;

destructor TListImpl.Destroy;
begin
  FList.Free;
  inherited;
end;

function GetListWithItems: IListIntf;
begin
  Result := TListImpl.Create;
  // add items to list
end;   
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,“实现自己”是解决所有问题的最终方法。我希望埋在劳教所的某个地方可以等我……不过还是谢谢你的回答! (2认同)