Thema: Delphi Property als Array

Einzelnen Beitrag anzeigen

Robert_G
(Gast)

n/a Beiträge
 

Re: Property als Array

  Alt 11. Jun 2005, 16:16
Zitat von leddl:
@malo:
Bei ner Add-Methode mußt du einfach nur an das Array ein neues Element anhängen...
Genau DAS sollte man nicht machen.
Wenn es eine array-basierte Liste sein soll sollte man sie stufenweise vergrößern.
Eine Vergrößerung auf 172% der alten Größe hat sich als bester Allroundwert gezeigt. Bei kleinen Datenmengen wäre es möglich den ersten Sprung relativ großzügig ausfallen zu lassen, dadurch würde man sich vielleicht kleine weitere Kopiererei antun müssen.
Außerdem verstehe ich diese Liste von "Operatoren" nicht ganz...

Eine Liste von Tokens könnte, um es ganz plain & easy zu machen, so aussehen:
Delphi-Quellcode:
type
   TToken = class
   // was immer du damit machen willst ;-)
   end;

   TTokenClass = class of TToken;
Delphi-Quellcode:
type
   TTokenListInherited = class(TObjectList)
  protected
      function getItem(aIndex: Integer): TToken; virtual;
      procedure setItem(aIndex: Integer; aToken: TToken); virtual;
   public
      function Add(aToken: TToken): Integer; virtual;
      function Remove(aToken: TToken): Integer; virtual;
      function IndexOf(aToken: TToken): Integer; virtual;
      function FindInstanceOf(aClass: TTokenClass;
                              aExact: Boolean = True;
                              aStartAt: Integer = 0): Integer; virtual;
      procedure Insert(aIndex: Integer; aToken: TToken); virtual;
      function First: TToken; virtual;
      function Last: TToken; virtual;
      property Items[Index: Integer]: TToken read getItem write setItem; default;
   end;

implementation

{ TTokenListInherited }

function TTokenListInherited.Add(aToken: TToken): Integer;
begin
   Result := inherited Add(aToken);
end;

function TTokenListInherited.FindInstanceOf(aClass: TTokenClass; aExact: Boolean;
   aStartAt: Integer): Integer;
begin
   Result := FindInstanceOf(aClass, aExact, aStartAt);
end;

function TTokenListInherited.First: TToken;
begin
   Result := inherited First() as TToken;
end;

function TTokenListInherited.getItem(aIndex: Integer): TToken;
begin
   Result := inherited GetItem(aIndex) as TToken;
end;

function TTokenListInherited.IndexOf(aToken: TToken): Integer;
begin
   Result := inherited IndexOf(aToken);
end;

procedure TTokenListInherited.Insert(aIndex: Integer; aToken: TToken);
begin
   inherited Insert(aIndex, aToken);
end;

function TTokenListInherited.Last: TToken;
begin
   Result := inherited Last() as TToken;
end;

function TTokenListInherited.Remove(aToken: TToken): Integer;
begin
   Result := inherited Remove(aToken);
end;

procedure TTokenListInherited.setItem(aIndex: Integer; aToken: TToken);
begin
   inherited setItem(aIndex, aToken);
end;
Da Tlist seine Methoden nicht virtual deklariert hat, ist es nicht möglich diese zu überschreiben um auf den Typen zu testen.
Es ist also möglich, die Liste auf TObjectList oder einen Vorfahren zu casten und einfach etwas anderes als einen Nachfahren von TToken reinzuwerfen.
Möglich wäre es also TObjectList zu verwenden anstatt davon abzuleiten.
Dadurch kannst du dir sicher sein, dass nur TToken Instanzen in die InnerList gelangen können.
Wie im oberen Beispiel ist keinerlei zusätzliche Logik nötig, da diese bereits von TList / TObjectList bereitgestellt wird.
Delphi-Quellcode:
type
   TObjectListClass = class of TObjectList;

   TTokenListNotInherited = class
   private
      fInnerList: TObjectList;
   protected
      property InnerList: TObjectList read fInnerList;
      function getItem(aIndex: Integer): TToken; virtual;
      procedure setItem(aIndex: Integer; aToken: TToken); virtual;
   public
      function Add(aToken: TToken): Integer; virtual;
      function Remove(aToken: TToken): Integer; virtual;
      function IndexOf(aToken: TToken): Integer; virtual;
      function FindInstanceOf(aClass: TTokenClass;
                              aExact: Boolean = True;
                              aStartAt: Integer = 0): Integer; virtual;
      procedure Insert(aIndex: Integer; aToken: TToken); virtual;
      function First: TToken; virtual;
      function Last: TToken; virtual;
      property Items[Index: Integer]: TToken read getItem write setItem; default;
      procedure Clear; virtual;

      constructor Create(); overload;virtual;
      constructor Create(aListClass :TObjectListClass); overload;virtual;
   end;

implementation

{ TTokenListNotInherited }

constructor TTokenListNotInherited.Create;
begin
   fInnerList := TObjectList.Create(True);
end;

constructor TTokenListNotInherited.Create(aListClass :TObjectListClass);
begin
   fInnerList := aListClass.Create(True);
end;

function TTokenListNotInherited.Add(aToken: TToken): Integer;
begin
   Result := InnerList.Add(aToken);
end;

procedure TTokenListNotInherited.Clear;
begin
   InnerList.Clear();
end;

function TTokenListNotInherited.FindInstanceOf(aClass: TTokenClass; aExact: Boolean;
   aStartAt: Integer): Integer;
begin
   Result := InnerList.FindInstanceOf(aClass, aExact, aStartAt);
end;

function TTokenListNotInherited.First: TToken;
begin
   Result := InnerList.First() as TToken;
end;

function TTokenListNotInherited.getItem(aIndex: Integer): TToken;
begin
   Result := InnerList[aIndex] as TToken;
end;

function TTokenListNotInherited.IndexOf(aToken: TToken): Integer;
begin
   Result := InnerList.IndexOf(aToken);
end;

procedure TTokenListNotInherited.Insert(aIndex: Integer; aToken: TToken);
begin
   InnerList.Insert(aIndex, aToken);
end;

function TTokenListNotInherited.Last: TToken;
begin
   Result := InnerList.Last() as TToken;
end;

function TTokenListNotInherited.Remove(aToken: TToken): Integer;
begin
   Result := InnerList.Remove(aToken);
end;

procedure TTokenListNotInherited.setItem(aIndex: Integer; aToken: TToken);
begin
   InnerList[aIndex] := aToken;
end;
Der zweite Weg ist zwar gehörig hässlich aber hat nicht die Lücke des oberen.
btw: TList suckz
  Mit Zitat antworten Zitat