Einzelnen Beitrag anzeigen

Robert_G
(Gast)

n/a Beiträge
 
#27

Re: Array of TStringList erzeugen

  Alt 2. Mai 2005, 16:38
Zitat von Kedariodakon:
Zitat von maximov:
@Kedariodakon: Es geht nicht um die dpCollection, sondern eher um die technik des templates. Damit kann man nämlich mit 4 zeilen code eine komplette typisierte objektliste erzeugen.
das ist schon klar, nur kann er nicht mal selber eine machen, wie soll das den dann mit der handhabung der dpCollection aussehen?
Ein Collection Descendant wäre hier doch total ungeeignet.
TCollection schluckt nur TCollectionItem-Nachfahren!
Will man Objekte verwalten wäre eine TObjectList ein passabler Anfang.

Und wen so ein Template interessiert...
Nix einfacher als das.
  • Du nimmst wie ich eine bestehende, eingestaubte Objectlist Ableitung
  • Eine Runde Search'nReplace um die Bezeichner so scheußlich wie möglich zu kriegen. (Sie sollten ja keineswegs mit "Real Life" Bezeichnern kollidieren.
  • ein bisschen bedingte Kompilierung (Die Einfachheit des Delphis Compilers ist hier mal ein Vorteil )
  • ->voilá

Nix weltbewegendes, auf kein Fall etwas schönes.... aber tierisch praktisch

Delphi-Quellcode:
{$IFNDEF TYPED_OBJECT_LIST_TEMPLATE}
unit TypedObjectList_template;

interface
uses
   Contnrs;

type _OBJECT_LIST_ITEM_ = TObject;

{$ENDIF TYPED_OBJECT_LIST_TEMPLATE}

{$IFNDEF TYPED_OBJECT_LIST_TEMPLATE_SECOND_PASS}

// Jedi's include to evaluate compiler version...
{$INCLUDE Jedi.inc}


type
   _OBJECT_LIST_IENUM_ = interface;
   _OBJECT_LIST_ENUM_ = class;
   _OBJECT_LIST_ = class(TObjectList)
   protected
      function GetItem(Index: Integer): _OBJECT_LIST_ITEM_; virtual;
      procedure SetItem(Index: Integer; const Value: _OBJECT_LIST_ITEM_); virtual;
   public
      function Add(aObject: _OBJECT_LIST_ITEM_): Integer; reintroduce; virtual;
      function Extract(Item: _OBJECT_LIST_ITEM_): _OBJECT_LIST_ITEM_; reintroduce; virtual;
      function Remove(aObject: _OBJECT_LIST_ITEM_): Integer; reintroduce; virtual;
      function IndexOf(aObject: _OBJECT_LIST_ITEM_): Integer; reintroduce; virtual;
      procedure Insert(Index: Integer; aObject: _OBJECT_LIST_ITEM_); reintroduce; virtual;
      function First: _OBJECT_LIST_ITEM_; reintroduce;
      function Last: _OBJECT_LIST_ITEM_; reintroduce;
      property Items[Index: Integer]: _OBJECT_LIST_ITEM_
         read GetItem
         write SetItem; default;

      function GetIEnumerator(): _OBJECT_LIST_IENUM_;
{$IFDEF COMPILER9_UP}
      function GetEnumerator(): _OBJECT_LIST_ENUM_;
{$ENDIF COMPILER9_UP}
   end;

   _OBJECT_LIST_IENUM_ = interface
      function MoveNext: Boolean;
      function GetCurrent: _OBJECT_LIST_ITEM_;
      property Current: _OBJECT_LIST_ITEM_ read GetCurrent;
   end;

   _OBJECT_LIST_ENUM_ = class(TInterfacedObject, _OBJECT_LIST_IENUM_)
   private
      fCollection: _OBJECT_LIST_;
      fIndex: Integer;
      constructor Create(List: _OBJECT_LIST_);
   public
      function MoveNext: Boolean;
      function GetCurrent: _OBJECT_LIST_ITEM_;
      property Current: _OBJECT_LIST_ITEM_ read GetCurrent;
   end;


{$ENDIF TYPED_OBJECT_LIST_TEMPLATE_SECOND_PASS}

{$IFNDEF TYPED_OBJECT_LIST_TEMPLATE}
implementation

{$DEFINE TYPED_OBJECT_LIST_TEMPLATE_SECOND_PASS}
{$ENDIF TYPED_OBJECT_LIST_TEMPLATE}

{$IFDEF TYPED_OBJECT_LIST_TEMPLATE_SECOND_PASS}

{ _OBJECT_LIST_ITEM_ }

function _OBJECT_LIST_.Add(aObject: _OBJECT_LIST_ITEM_): Integer;
begin
   RESULT := inherited Add(aObject);
end;

function _OBJECT_LIST_.Extract(Item: _OBJECT_LIST_ITEM_): _OBJECT_LIST_ITEM_;
begin
   RESULT := _OBJECT_LIST_ITEM_(inherited Extract(Item));
end;

function _OBJECT_LIST_.First: _OBJECT_LIST_ITEM_;
begin
   RESULT := _OBJECT_LIST_ITEM_(inherited First());
end;

function _OBJECT_LIST_.GetItem(Index: Integer): _OBJECT_LIST_ITEM_;
begin
   RESULT := _OBJECT_LIST_ITEM_(inherited Items[Index]);
end;

function _OBJECT_LIST_.IndexOf(aObject: _OBJECT_LIST_ITEM_): Integer;
begin
   RESULT := inherited IndexOf(aObject);
end;

procedure _OBJECT_LIST_.Insert(Index: Integer; aObject: _OBJECT_LIST_ITEM_);
begin
   inherited Insert(Index, aObject);
end;

function _OBJECT_LIST_.Last: _OBJECT_LIST_ITEM_;
begin
   RESULT := _OBJECT_LIST_ITEM_(inherited Last());
end;

function _OBJECT_LIST_.Remove(aObject: _OBJECT_LIST_ITEM_): Integer;
begin
   RESULT := inherited Remove(aObject);
end;

procedure _OBJECT_LIST_.SetItem(Index: Integer;   const Value: _OBJECT_LIST_ITEM_);
begin
   inherited Items[Index] := Value;
end;

{$IFDEF COMPILER9_UP}

function _OBJECT_LIST_.GetEnumerator: _OBJECT_LIST_ENUM_;
begin
  RESULT := _OBJECT_LIST_ENUM_.Create(self);
end;

function _OBJECT_LIST_.GetIEnumerator: _OBJECT_LIST_IENUM_;
begin
   RESULT := GetEnumerator();
end;

{$ELSE}

function _OBJECT_LIST_.GetIEnumerator: _OBJECT_LIST_IENUM_;
begin
   RESULT := _OBJECT_LIST_ENUM_.Create(self);
end;

{$ENDIF COMPILER9_UP}

constructor _OBJECT_LIST_ENUM_.Create(List: _OBJECT_LIST_);
begin
  fIndex := -1;
  fCollection := List;
end;

function _OBJECT_LIST_ENUM_.GetCurrent: _OBJECT_LIST_ITEM_;
begin
  RESULT := fCollection.GetItem(fIndex);
end;

function _OBJECT_LIST_ENUM_.MoveNext: Boolean;
begin
  inc(fIndex);
   RESULT := (fIndex > -1) and (fIndex < fCollection.Count);
end;


{$WARNINGS off}
{$IFNDEF TYPED_OBJECT_LIST_TEMPLATE}
end.
{$ENDIF TYPED_OBJECT_LIST_TEMPLATE}
{$ENDIF TYPED_OBJECT_LIST_TEMPLATE_SECOND_PASS}
{$DEFINE TYPED_OBJECT_LIST_TEMPLATE_SECOND_PASS}
Die Verwendung ist denkbar einfach (die 4 Zeilen, von denen maximov sprach )
Delphi-Quellcode:
interface
uses Contnrs; /// <- wichtig!

type
   TSomeClass = class
   private
      fSomeProperty: Integer;
   public
      property SomeProperty: Integer
         read fSomeProperty
         write fSomeProperty;
   end;


{$DEFINE TYPED_OBJECT_LIST_TEMPLATE}
type _OBJECT_LIST_ITEM_ = TSomeClass;
{$INCLUDE TypedObjectList_template.pas}
   TSomeClassList = _OBJECT_LIST_;
implementation
{$INCLUDE TypedObjectList_template.pas}
end.
direkt angewand könnte man vor D2005 so durch sie laufen:
Delphi-Quellcode:
   with SomeClassList.GetIEnumerator() do
      while MoveNext() do
         WriteLn(Current.SomeProperty);
In D2005 geht nun auch gleich das hier:
Delphi-Quellcode:
var
   SomeInstance :TSomeClass;
begin
   for SomeInstance in SomeClassList do
      WriteLn(SomeInstance.SomeProperty);
  Mit Zitat antworten Zitat