Autor |
Beitrag |
doublecross
Beiträge: 149
Erhaltene Danke: 27
Windows 7
C#; Visual Studio 2015
|
Verfasst: Fr 29.09.17 10:39
Hi,
gerd8888 hat folgendes geschrieben : | Ich bin mir jetzt auch nicht mehr ganz sicher. Normalerweise nimmt man NIL her. Das geht 100 prozentig. |
"man" ist immer relativ. Da ich auch ganz gerne mal die Sprace wechsel und soetwan hüben meist anderes läuft als drüben prüfe ich z.B. gerne auf < 1, dass klappt eigentlich immer bei "Anzahl Elemente" Prüfungen. Das ist ja das schöne beim Programmieren, solange es funktioniert ist es richtig - alles andere ist nur Religion.
|
|
drstar
Beiträge: 79
Erhaltene Danke: 2
Windows 8.1/x64
Delphi 10.1
|
Verfasst: Fr 29.09.17 11:32
OlafSt hat folgendes geschrieben : | gerd888 erzählt Unsinn. Wenn die TObjectList<> nicht initialisiert ist, ist die ganze ObjectList Nil. Ein Zugriff auf das Count-Property gibt dann auch prompt eine Exception.
|
Die Liste wird natürlich schon beim create initialisiert, daher kann an dieser Stelle keine Exception auftreten. Bevor ich aber blind auf vermeintliche Elemente der Liste zugreifen will, will ich natürlich feststellen, ob sich überhaupt schon Einträge in der Liste befinden. Die Prüfung auf 0 scheint nicht zu funktionieren, denn auch eine leere Liste ergibt 0, und zumindest bei meinem Test auch mit genau 1 Element. Ansonsten mache ich an anderer Stelle irgendetwas falsch. Die einzige Option, die mir bliebe, wäre ein "blindes" Element beim create einzufügen und das fortan zu ignorieren - dann ergibt die Prüfung beim Count natürlich, sobald ich ein "echtes" Element der Liste hinzufüge, Count > 0. Wäre zwar nicht schön, aber im Zweifelsfalle könnte ich damit leben. Gibt's halt ein nicht benutztes Element in der Liste...
|
|
OlafSt
Beiträge: 486
Erhaltene Danke: 99
Win7, Win81, Win10
Tokyo, VS2017
|
Verfasst: Fr 29.09.17 12:56
Das eine Liste mit einem eingefügten Element trotzdem ein Count=0 zurückgeben soll, halte ich für ausgeschlossen. Dann wären die einschlägigen Foren voll mit Threads zu diesem Thema.
Ich tippe dann eher darauf, das das Element gar nicht eingefügt wird (weil es zu dem Zeitpunkt schon wieder/noch nil ist, oder da ist irgendwo ein Liste.Clear; versehentlich reingerutscht, oder oder oder...
_________________ Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
|
|
drstar
Beiträge: 79
Erhaltene Danke: 2
Windows 8.1/x64
Delphi 10.1
|
Verfasst: Fr 29.09.17 13:21
OlafSt hat folgendes geschrieben : | Das eine Liste mit einem eingefügten Element trotzdem ein Count=0 zurückgeben soll, halte ich für ausgeschlossen. Dann wären die einschlägigen Foren voll mit Threads zu diesem Thema.
Ich tippe dann eher darauf, das das Element gar nicht eingefügt wird (weil es zu dem Zeitpunkt schon wieder/noch nil ist, oder da ist irgendwo ein Liste.Clear; versehentlich reingerutscht, oder oder oder... |
In der Tat liegt der Fehler woanders - beim Überwachen ergab ein Element im .Count auch 1. Also Prüfung auf > 0 ist korrekt. Ich bin noch nicht dahinter gestiegen, was bei mir das Problem verursacht, aber ich vermute folgendes:
main.pas
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure main begin Datenbank.NewKlient(Klient); end;
procedure Liste_aktualisieren; var lListe: TObjectList<TKlient>; begin lListe := TObjectList<TKlient>.create(true); Datenbank.GetKlientenliste(lListe); end; |
database.pas
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
| type Datenbank = class(TObjeckt) public procedure NewKlient(Klient: TKlient) procedure GetKlientenliste(Liste: TObjectList<TKlient>); private procedure StoreValue(Klient: TKlient); overload iKlientliste : TObjectList<TKlient>; end;
procedure Datenbank.NewKlient; overload; begin end;
procedure Datenbank.GetKlientenliste(Liste: TObjectList<TKlient>); var i: integer; begin Liste := TObjectList<TKlient>.create(true); if iKlientliste.count > 0 then begin for i := 1 to iKlientliste.count do Liste[i] := iKlientliste[i]; end else Liste := Nil; end; end; |
Für mich scheint es so, als gäbe es bei der Übergabe der Liste aus der Get-Methode der Datenbank-Klasse zu einem Problem. Wie bekomme ich die Liste übergeben?
|
|
jasocul
Beiträge: 6388
Erhaltene Danke: 146
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Fr 29.09.17 13:40
Count gibt die Anzahl der Elemente an. Das ist wohl klar.
Deine Schleife geht von 1 bis Count.
Immer daran denken, dass der Listen-Index immer bei 0 anfängt!
Deine Schleife muss also so aussehen:
Delphi-Quelltext 1: 2:
| for i := 0 to iKlientliste.count-1 do Liste[i] := iKlientliste[i]; |
Abgesehen davon, dass du dein Listen-Objekt zweimal erzeugst. Einmal vor GetKlientenliste und dann noch innerhalb dieser Methode.
Außerdem müsste es innerhalb der Zuweisung in deiner Schleife auch knallen. Deine Zielliste hat noch keinen Inhalt. Der Zugriff mit Liste[i] muss eine Exception verursachen, da ein Listen-Element mit diesem Index noch gar nicht existiert.
|
|
drstar
Beiträge: 79
Erhaltene Danke: 2
Windows 8.1/x64
Delphi 10.1
|
Verfasst: Fr 29.09.17 13:51
jasocul hat folgendes geschrieben : | Count gibt die Anzahl der Elemente an. Das ist wohl klar.
Deine Schleife geht von 1 bis Count.
Immer daran denken, dass der Listen-Index immer bei 0 anfängt!
Deine Schleife muss also so aussehen:
Delphi-Quelltext 1: 2:
| for i := 0 to iKlientliste.count-1 do Liste[i] := iKlientliste[i]; |
Abgesehen davon, dass du dein Listen-Objekt zweimal erzeugst. Einmal vor GetKlientenliste und dann noch innerhalb dieser Methode.
Außerdem müsste es innerhalb der Zuweisung in deiner Schleife auch knallen. Deine Zielliste hat noch keinen Inhalt. Der Zugriff mit Liste[i] muss eine Exception verursachen, da ein Listen-Element mit diesem Index noch gar nicht existiert. |
Den Schleifen-Index habe ich jetzt auf 0.. count-1 umgestellt, aber das führt leider auch nicht zum Erfolg. Die Schleife läuft tadellos durch, und laut Überwachung wird die Liste in der Get-Methode der Datenbank auch befüllt. Die Liste kommt aber in der Main nie an, sondern ist immer Nil. Das mit dem doppelt erzeugen habe ich mir auch schon gedacht, hab mal testweise das .create in der Datenbank rausgenommen, ändert aber leider nichts, außer das es nicht zu einem anderen Fehler kommt, was für mich den Schluß zuläßt, das das .create in der Get-Methode nichts zu suchen hat. Knackpunkt scheint aber die Übergabe/Rückgabe der Liste zu sein.
|
|
jasocul
Beiträge: 6388
Erhaltene Danke: 146
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Fr 29.09.17 14:01
|
|
jasocul
Beiträge: 6388
Erhaltene Danke: 146
Windows 7 + Windows 10
Sydney Prof + CE
|
Verfasst: Fr 29.09.17 14:07
Noch ein paar Korrekturen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure Datenbank.GetKlientenliste(var Liste: TObjectList<TKlient>); var i: integer; begin if not Assigned(Liste) then Liste := TObjectList<TKlient>.create(true); if iKlientliste.count > 0 then begin for i := 0 to iKlientliste.count-1 do Liste[i] := iKlientliste[i]; end else begin Liste.Free; Liste := Nil; end; end; end; |
|
|
drstar
Beiträge: 79
Erhaltene Danke: 2
Windows 8.1/x64
Delphi 10.1
|
Verfasst: Fr 29.09.17 14:40
|
|