mandag den 31. oktober 2011

"For in"-operatoren ved hjælp af Generics

I et tidligere indlæg viste jeg, hvordan man lavede en "for in"-operator i Delphi 2007. Dette indlæg vil kort vise, hvordan det gøres ved hjælp af generics, og således i Delphi 2009 og senere.

Til forskel fra tidligere (pre generics), hvor man skulle implementere sine egne lister vha. nedarvning for at få den type stærke, klares det i dag med nogle enkelte linjers kode, og erklæringen af selve listen er kun en enkelt linjes kode.

For eksemplets skyld bruger jeg den samme liste som vist i det tidligere indlæg.

unit MyListU;

interface

uses
  Generics.Collections;

type
  TMyClass = class
  private
    FSomeString: String;
    FSomeInteger: Integer;
    procedure SetSomeInteger(const Value: Integer);
    procedure SetSomeString(const Value: String);
  public
    property SomeInteger: Integer read FSomeInteger write SetSomeInteger;
    property SomeString: String read FSomeString write SetSomeString;
  end;

  TMyList = TObjectList<TMyClass>;

implementation

{ TMyClass }

procedure TMyClass.SetSomeInteger(const Value: Integer);
begin
  FSomeInteger := Value;
end;

procedure TMyClass.SetSomeString(const Value: String);
begin
  FSomeString := Value;
end;

end.

Som det ses, er der betragteligt mindre kode end i Delphi 2007-versionen: 108 linjer i 2007-versionen og kun 36 i den ovenstående! "Besparelsen" er til at få øje på.

"For in"-operatoren "opstår af sig selv", så man kan straks tage sin liste i brug og iterere gennem listen :

procedure TMainForm.BtnTest1Click(Sender: TObject);
var
  MyList : TMylist;
  MyObject : TMyClass;
begin
  MyList := TMylist.Create;
  //Todo: Tilføj elementer

  for MyObject in MyList do
    begin
      //Todo : brug MyObject
    end;

  FreeAndNil(MyList);
end;


Nemt og enkelt og uden nogle ben. Men hvad så hvis man ikke vil bruge et objekt til løbe min liste i gennem, men kun vil kigge på fx. integer-delen af objektet? Eller hvad nu hvis man ønsker flere muligheder for at traversere listen igennem? Ja, så er man nødt til at lave sin egen enumerator-klasse, som arver fra TEnumerator<T>, men det vil jeg behandle i et andet indlæg.

So stay tuned!

Jens Borrisholt

Ingen kommentarer:

Send en kommentar