【问题标题】:"Stack overflow" error with Generic TList.SortGeneric TList.Sort 出现“堆栈溢出”错误
【发布时间】:2016-02-06 13:40:00
【问题描述】:

我已经实现了 Generics.Defaults.TComparer 来对类型化的 TList 进行排序。但是调用 Sort 方法时,会抛出异常“Stack overflow at...”

为什么会出现堆栈溢出错误?

// Declarations

  TOrder = record
    ID: Integer;
    OrderDate: TDate;
  end;

  POrder = ^TOrder;

  FOrderList: TList<POrder>;

  TComparer_OrderDate = class(TComparer<POrder>)
  public
    function Compare(const a, b: POrder): Integer; override;
  end;

function TComparer_OrderDate.Compare(const a, b: POrder): Integer;
begin
  Result := 0;

  if (a^.OrderDate> b^.OrderDate) then
    Result := 1
  else
    Result := -1;
end;


  // This code inside a button OnClick event: 
  FOrderList := TList<POrder>.Create;

  FComparer_OrderDate := TComparer_OrderDate.Create;

  FOrderList.Sort(FComparer_OrderDate); // <--- 'stack overflow' error.

【问题讨论】:

标签: delphi delphi-10-seattle tlist


【解决方案1】:

您的比较函数需要返回 0 表示相等。像这样:

function TComparer_OrderDate.Compare(const a, b: POrder): Integer;
begin  
  if (a^.OrderDate > b^.OrderDate) then
    Result := 1
  else if (a^.OrderDate < b^.OrderDate) then
    Result := -1
  else
    Result := 0;
  end;
end;

使用TComparer&lt;POrder&gt;.Construct 做比较器更容易。

FOrderList.Sort(
  TComparer<POrder>.Construct(
    function(const a, b: POrder): Integer
    begin  
      if (a^.OrderDate > b^.OrderDate) then
        Result := 1
      else if (a^.OrderDate < b^.OrderDate) then
        Result := -1
      else
        Result := 0;
      end;
    end
  )
);

或者使用默认的日期时间比较器:

DateTimeComparer := TComparer<TDateTime>.Default;
FOrderList.Sort(
  TComparer<POrder>.Construct(
    function(const a, b: POrder): Integer
    begin  
      Result := DateTimeComparer.Compare(a^.OrderDate, b^.OrderDate);
    end
  )
);

我没有编译任何这些,所以我预计会有一些小错误。

【讨论】:

    猜你喜欢
    • 2014-04-10
    • 2014-01-26
    • 2019-02-16
    • 2011-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多