Jeg formoder at alle bekendt med, at Delphi fra version 2009 har generiske typer. Herunder generiske lister.
Helt kort: Hvis man skal bruge en type stærk liste af en bestemt type - det kan være en simpletype, en klasse eller en record - så skal man:
1) Uses Generics.Collections
2) Erklære en variable: List : TList<TMyType>;
3) Kalde dens constructor: List := TList<TMyType>.Create;
... Og så bruger man den bare som en almindelig typestærk liste.
Et lille hurtigt eksempel kunne se således ud:
procedure Demo; var i: Integer; PointList: TList<TPoint>; begin PointList := TList<TPoint>.Create; for i := 1 to 10 do PointList.Add(Point(Random(100), Random(100))); PointList.Sort; FreeAndNil(PointList); end;
MEEEN! Nu er det behovet opstår for SELV at bestemme, hvordan listen skal sorteres.
I Delphi kan man ikke bruge lighedsoperatoren til at sammenligne to generiske elementer i listen med. I stedet for implementerer man sin egen TComparer og giver den med - enten til listens constructor eller til sorteringen. I det følgende vælger jeg at sortere mine punkter efter afstanden til centrum, men først lige en lille hjælper, som giver mig et par metoder på min TPoint:
TPointHelper = record helper for TPoint public function DistanceToCenterSquare: Integer; inline; function DistanceToCenter: Extended; inline; end; { TPointHelper } function TPointHelper.DistanceToCenter: Extended; begin Result := Sqrt(DistanceToCenterSquare); end; function TPointHelper.DistanceToCenterSquare: Integer; begin Result := X * X + Y * Y; end;
Og så skal vi have vore TComparer implementeret:
type
TPointComparer = class(TComparer<TPoint>)
function Compare(const Left, Right: TPoint): Integer; override;
end;
{ TPointComparer }
function TPointComparer.Compare(const Left, Right: TPoint): Integer;
begin
Result := Left.DistanceToCenterSquare - Right.DistanceToCenterSquare;
end;
Tilbage er der blot at tage vores nye klasse i brug:
procedure Demo2; var i: Integer; PointList: TList<TPoint>; begin PointList := TList<TPoint>.Create(TPointComparer.Create); for i := 1 to 10 do PointList.Add(Point(Random(100), Random(100))); PointList.Sort; FreeAndNil(PointList); end;
BEMÆRK: TList er ikke trådsikker. Ej heller TList<T>. Hvordan løser man så det
Ingen kommentarer:
Send en kommentar