3

如果我们查看 XE2 或 XE3 的TObjectList 方法的在线帮助 ,我们会看到二进制搜索功能可用于 TObjectList。但如果我们尝试使用 XE3,它甚至无法编译。

例如,排序功能也可用,但这是编译的。

欢迎任何想法。

示例代码:

unit FM_Main;

  interface

  uses
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Contnrs, Vcl.CheckLst, System.Generics.Collections;

  type
     TTPRODData = class
     private
        FData1 : String;
        FData2 : String;

        FCount : Integer;
     public
        constructor Create; overload;
        destructor Destroy; override;
     end;

     TTPRODDataList = class(TObjectList)

        function GetItem(Index: Integer): TTPRODData;
        procedure SetItem(Index: Integer; const Value: TTPRODData);
     public
        constructor Create; overload;
        destructor  Destroy; override;

        property Items[Index: Integer]: TTPRODData read GetItem write SetItem; default;
        procedure SortOnProductCode;

     end;

    TForm1 = class(TForm)
      Button1: TButton;
      procedure Button1Click(Sender: TObject);
    private
      { Private declarations }
    public
      { Public declarations }
    end;

  var
    Form1: TForm1;

  implementation

  {$R *.dfm}

  //
  // Sort function.
  //
  function CompareProductCode(Item1, Item2: Pointer): Integer;
  begin
     Result := CompareStr(TTPRODData(Item1).FData1, TTPRODData(Item2).FData1);
  end;

  //
  //
  //

  procedure TForm1.Button1Click(Sender: TObject);
  var
     aProdList : TTPRODDataList;
     aDummy : TTPRODData;
     aNdx : Integer;

  begin
     aProdList := TTPRODDataList.Create;

     // This call works.
     aProdList.Sort(CompareProductCode);

     // This call doesn't even compile !
     aProdList.BinarySearch(aDummy, aNdx);
  end;

  { TTPRODData }

  constructor TTPRODData.Create;
  begin
     inherited Create;

     FData1 := '';
     FData2 := '';
     FCount := 0;
  end;

  destructor TTPRODData.Destroy;
  begin
    inherited;
  end;

  { TTPRODDataList }

  constructor TTPRODDataList.Create;
  begin
     inherited Create;
  end;

  destructor TTPRODDataList.Destroy;
  begin
     Clear;

     inherited;
  end;

  function TTPRODDataList.GetItem(Index: Integer): TTPRODData;
  begin
     result := TTPRODData(inherited GetItem(index));
  end;

  procedure TTPRODDataList.SetItem(Index: Integer; const Value: TTPRODData);
  begin
     inherited setItem(index, value);
  end;

  procedure TTPRODDataList.SortOnProductCode;
  begin
     Sort(CompareProductCode);
  end;

  end.

正如 David Heffernan 所建议的,这里遵循排序函数的比较器代码。

对于那些感兴趣的人,这里遵循比较器方法的代码:

TTProdComparer = class(TComparer<TTPRODData>)
public
   function Compare(const Item1, Item2: TTPRODData): Integer; override;
end;

And the code :
{ TTProdComparer }
function TTProdComparer.Compare(const Item1, Item2: TTPRODData): Integer;
begin
   Result := CompareStr(Item1.FData1 , Item2.FData1 );
end;
4

1 回答 1

7

您链接到的文档适用TObjectList<T>于该Generics.Collections单元的通用容器。

TObjectList但是您在代码中使用的类是单元中遗留的非通用容器Contnrs

您尝试使用的BinarySearch方法仅存在于泛型类上。

如果您切换到通用容器,那么您会发现您可以从您的课程中删除大部分样板代码。它成为了:

TTPRODDataList = class(TObjectList<TTPRODData>)
public
  procedure SortOnProductCode;
end;

您不需要GetItemSetItem并且Items因为类型安全的泛型类已经对该功能进行了排序。

您要做的唯一工作是调整您的排序代码以适应 Delphi 通用容器使用的稍微不同的接口。

于 2013-01-30T08:13:50.270 回答