AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Property als Array

Ein Thema von malo · begonnen am 11. Jun 2005 · letzter Beitrag vom 25. Aug 2005
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von malo
malo

Registriert seit: 19. Sep 2004
2.115 Beiträge
 
#1

Property als Array

  Alt 11. Jun 2005, 14:07
Hi!

Ich habe ein kleines Problem... und zwar will ich eine Property als Array verwenden. Ich hab es so versucht:

property Operators[Ndx: integer]: String read fOperators write fOperators; fOperators ist dabei ein array of string. Ich bekomm dann jedoch den Fehler "inkompatible Typen: 'dynamic Array' und 'Procedure'".

Ich hab auch versucht, den Index von der Property wegzulassen. Ändert jedoch nichts...

Aus der Fehlermeldung schließe ich, dass ich die Get- und Set-Methode mit einer Prozedur ausführen muss...

Aber wie genau funktioniert das ganze dann?
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#2

Re: Property als Array

  Alt 11. Jun 2005, 14:13
Delphi-Referenz durchsuchenArray-Properties
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#3

Re: Property als Array

  Alt 11. Jun 2005, 14:15
Schreib doch einfach
property Operators[Ndx: integer]: String read GetOperators write SetOperators; und drück Strg + Shift + C, dann macht Delphi schon die halbe Arbeit .
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Benutzerbild von leddl
leddl

Registriert seit: 13. Okt 2003
Ort: Künzelsau
1.613 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Property als Array

  Alt 11. Jun 2005, 14:21
Um ein Item des Array zu bekommen, greifst du einfach über die getMethode darauf zu:
Delphi-Quellcode:
function getArrayItem(Index : Integer) : String;
Begin
//Bereichsprüfung nicht vergessen!
if (Index > -1) and (Index < high(fArray)) Then
  result := fArray[Index];
else
//Oder was auch immer, vielleicht sogar ne Exception,...
  result := '';
End;
Analog bei der setMethode. Um ein neues Item hinzuzufügen brauchst du dann halt ne extra Methode.
Axel Sefranek
A programmer started to cuss, cause getting to sleep was a fuss.
As he lay there in bed, looping round in his head
was: while(!asleep()) ++sheep;
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#5

Re: Property als Array

  Alt 11. Jun 2005, 14:27
Zitat von leddl:
Um ein Item des Array zu bekommen, greifst du einfach über die getMethode darauf zu:
Delphi-Quellcode:
function getArrayItem(Index : Integer) : String;
Begin
//Bereichsprüfung nicht vergessen!
if (Index > -1) and (Index < high(fArray)) Then
  result := fArray[Index];
else
//Oder was auch immer, vielleicht sogar ne Exception,...
  result := '';
End;
Analog bei der setMethode. Um ein neues Item hinzuzufügen brauchst du dann halt ne extra Methode.
Müsste es nicht
if (Index > -1) and (Index <= High(fArray)) then heißen ?
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
Benutzerbild von malo
malo

Registriert seit: 19. Sep 2004
2.115 Beiträge
 
#6

Re: Property als Array

  Alt 11. Jun 2005, 14:34
Mein Code bis jetzt:

Delphi-Quellcode:
type
  TTokens = class
    private
      fOperators: array of string;
      function GetOperators(Index: integer): string;
      procedure SetOperators(Index: integer; s: string);
    public
      property Operators[Ndx: integer]: String read GetOperators write SetOperators;
  end;
//...

procedure TTokens.SetOperators(Index: integer; s: string);
begin
  if Index < high(fOperators) then
    fOperators[Index] := s;
end;

function TTokens.GetOperators(Index: integer): string;
begin
if (Index > -1) and (Index <= high(fOperators)) Then
  result := fOperators[Index]
else
  result := '';
end;
Ist das so richtig (bis auf den fehlenden Else-Zweig in der Set-Methode)? Und wie muss ich die Add-Methode implementieren?
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#7

Re: Property als Array

  Alt 11. Jun 2005, 14:35
Nein, du prüft beim Setter wieder ein element zu wenig. mach am besten bei beidem < length ()
  Mit Zitat antworten Zitat
Benutzerbild von leddl
leddl

Registriert seit: 13. Okt 2003
Ort: Künzelsau
1.613 Beiträge
 
Delphi 2006 Professional
 
#8

Re: Property als Array

  Alt 11. Jun 2005, 16:46
@Khabarakh:
Jupp, das is mir durchgeflutscht

@malo:
Bei ner Add-Methode mußt du einfach nur an das Array ein neues Element anhängen...
Axel Sefranek
A programmer started to cuss, cause getting to sleep was a fuss.
As he lay there in bed, looping round in his head
was: while(!asleep()) ++sheep;
  Mit Zitat antworten Zitat
Robert_G
(Gast)

n/a Beiträge
 
#9

Re: Property als Array

  Alt 11. Jun 2005, 17: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
Benutzerbild von malo
malo

Registriert seit: 19. Sep 2004
2.115 Beiträge
 
#10

Re: Property als Array

  Alt 11. Jun 2005, 17:41
Das ist ja ein ganz schöner Brocken...

Naja, manchmal kommt mir schon mal die bekannte Frage auf: Warum einfach, wenn es auch kompliziert geht?

Meine "Liste von Operatoren" ist dafür da, dass man für meine "Programmiersprache" Operatoren hinzufügen bzw. prüfen kann.

Das ganze hab ich gemacht, weil ich in diese Liste jeden Operator reinschreiben wollte, den es in dieser "Programmiersprache" geben sollte. Bei meinem Tokenizer sollte dann geprüft werden, ob das jeweilige Zeichen meines Sourcecodes ein Operator ist.

Dafür die "Liste von Operatoren". Ich könnte natürlich auch eine Konstantenarray verwenden, aber ich weiß nicht, inwieweit ich meine Sprache noch erweitern will. Daher wollte ich ein variables Array nehmen. Und wegen der OOP wollte ich halt nicht unbedingt Public-Variablen verwenden, sondern lieber eine Property.


Und ich gehe nicht für eine solch kleine Liste so große Umwege wie Robert mir vorschlagen will. Manches ist echt zu viel des Guten. Ich bin dir zwar sehr dankbar für deine Mühen, Robert, aber ich verstehe einfach nicht, wofür all das notwendig ist. Ich persöhnlich komme jederzeit auch gut mit einem einfachen Array klar. Wozu also eine TObjectList UND eine Klasse, in der die meisten (oder alle?) der ObjectList-Methoden drin vorkommen, die im Endeffekt nur die gleiche Methode einer echten TObjectList aufrufen. Ich halte sowas nicht nur für unnötig, sondern auch noch für Zeitverschwendung.

Sorry, aber das musste einfach mal raus. Man muss nicht für ALLES eine eigene Klasse haben.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:37 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz