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;

タイプ セーフなジェネリック クラスには既にその機能がソートされているため、GetItemは必要SetItemありません。Items

あなたがしなければならない唯一の作業は、Delphi 汎用コンテナで使用される若干異なるインターフェイスに適合するようにソート コードを適応させることです。

于 2013-01-30T08:13:50.270 に答える