2013-01-30 5 views
3

에 대한 XE2 또는 XE3의 온라인 도움말을 보면 binarysearch 함수가 TObjectList에 액세스 할 수 있습니다. 그러나 우리가 XE3에 들어가면 컴파일조차되지 않습니다.TObjectList에 대해 Binarysearch 함수를 호출 할 수 없습니다.

예를 들어 sort 함수도 사용할 수 있지만이 함수는 컴파일됩니다.

모든 아이디어를 환영합니다.

샘플 코드 : 데이비드 헤퍼에 의해

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. 

제안으로, 여기에 정렬 기능에 대한 비교 자에 대한 규정을 따르십시오.

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; 

답변

7

당신이에 연결 한 문서가 Generics.Collections 장치에서 일반 컨테이너 TObjectList<T>입니다 : 비교 부 방법에 대한 규정을 따르 여기에 관심이있는 사람들을 위해

.

그러나 코드에서 사용한 클래스는 Contnrs 단위의 기존 제너릭 컨테이너 TObjectList입니다.

사용하려는 BinarySearch 메서드는 제네릭 클래스에만 있습니다.

일반 컨테이너로 전환하면 대부분의 보일러 플레이트 코드를 클래스에서 제거 할 수 있습니다. 그것은된다 : 유형 안전 제네릭 클래스가 이미 정렬하는 기능을 가지고 있기 때문에 당신은 GetItem, SetItemItems 필요하지 않습니다

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

.

당신이해야 할 일은 Delphi 제네릭 컨테이너에서 사용되는 다소 다른 인터페이스에 맞게 정렬 코드를 수정하는 것입니다.