| Autor |
Beitrag |
Wonko
      
Beiträge: 69
|
Verfasst: Mo 01.10.07 13:08
Hallo,
ich habe ein Problem, das ich lösen kann, von dem ich aber nicht weis, wieso ich es habe.
Zwei verschachtelte with-Strukturen geben mir eine EAccessViolation, wenn ich die Methoden und Eigenschaften direkt ihren Objekten zuordne klappt alles. Laut Delphi-Hilfe kann man with verschachteln, wo ist der Fehler?
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:
| with TListBox(FindComponent('ListBox'+LBNr)) do for i:=Count-1 downto 0 do if Selected[i]=true then with TClientDataSet(FindComponent('CDS'+LBNr)) do begin RecNo:=ItemIndex+1; Delete; MergeChangeLog; SaveToFile(); end;
for i:=TListBox(FindComponent('ListBox'+LBNr)).Count-1 downto 0 do if TListBox(FindComponent('ListBox'+LBNr)).Selected[i]=true then begin TClientDataSet(FindComponent('CDS'+LBNr)).RecNo:=TListBox(FindComponent('ListBox'+LBNr)).ItemIndex+1; TClientDataSet(FindComponent('CDS'+LBNr)).Delete; TClientDataSet(FindComponent('CDS'+LBNr)).MergeChangeLog; TClientDataSet(FindComponent('CDS'+LBNr)).SaveToFile(); end;
|
Ich hoffe, Ihr könnt mir das erklären, Dank schonmal im Voraus.
|
|
Stefan.Buchholtz
      
Beiträge: 612
WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
|
Verfasst: Mo 01.10.07 13:25
Die TListBox in deinem äusseren with-Statement ist ja ebenfalls eine Komponente, die die Methode FindComponent kennt. Deswegen wird in dem inneren with-Statement das FindComponent der ListBox aufgerufen statt dem des Formulars. Da kommt natürlich nil zurück, so dass alles innerhalb des inneren with Zugriffsverletzungen werfen muss.
Diese netten Fehlerquellen sind der Grund, warum ich persönlich with für böse halte - wir haben hier in unseren Coding-Richtlinien die Verwendung von with verboten.
Stefan
_________________ Ein Computer ohne Windows ist wie eine Schokoladentorte ohne Senf.
|
|
jaenicke
      
Beiträge: 19345
Erhaltene Danke: 1753
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 01.10.07 13:32
Ich benutze with auch nicht, es bringt ja auch nix. Und es gibt noch einen anderen Grund, warum with nicht so gut ist. Beim Kompilieren wird das, was in with steht ja nur vor vor entsprechenden Befehle eingesetzt. Das heißt es wird in diesem Fall hier jedesmal wieder FindComponent aufgerufen (zumindest habe ich die Beschreibung so verstanden).
Damit ist das eine deutliche Performance-Bremse. Ich speichere in so einem Fall einfach das Objekt in eine Variable und benutze dann immer diese, womit der Code auch übersichtlicher ist, aber erstens die angesprochene Fehlerquelle nicht existiert und zweitens auch keine Performancenachteile auftreten.
|
|
Stefan.Buchholtz
      
Beiträge: 612
WIN 2000, WIN XP, Mac OS X
D7 Enterprise, XCode, Eclipse, Ruby On Rails
|
Verfasst: Mo 01.10.07 14:36
jaenicke hat folgendes geschrieben: | Ich benutze with auch nicht, es bringt ja auch nix. Und es gibt noch einen anderen Grund, warum with nicht so gut ist. Beim Kompilieren wird das, was in with steht ja nur vor vor entsprechenden Befehle eingesetzt. Das heißt es wird in diesem Fall hier jedesmal wieder FindComponent aufgerufen (zumindest habe ich die Beschreibung so verstanden).
Damit ist das eine deutliche Performance-Bremse. Ich speichere in so einem Fall einfach das Objekt in eine Variable und benutze dann immer diese, womit der Code auch übersichtlicher ist, aber erstens die angesprochene Fehlerquelle nicht existiert und zweitens auch keine Performancenachteile auftreten. |
Nein, das ist meines Wissens nicht so - with wertet den Ausdruck nur einmal aus und arbeitet mit einer verborgenen Variable. Einen Performance-Nachteil gegenüber einer expliziten Variable zum Zwischenspeichern bringt das nicht.
In dem Codebeispiel hier würde ich allerdings FindComponent gar nicht benutzen. Wenn ich etwas mit mehreren Komponenten in einem Formular machen will, speichere ich diese im FormCreate-Event in einer Liste oder einem Array und greife darüber auf die Komponente zu. Das ist erstens performanter als FindComponent, weil es die lineare Suche durch alle Komponente spart und führt ausserdem die Überprüfung, ob die Komponente überhaupt auf dem Formular existiert, schon zur Compile-Zeit durch. Bei obigem Code hagelt es dagegen sofort Zugriffsverletzungen, wenn jemand z.B. eine der Komponenten umbenennt.
Stefan
_________________ Ein Computer ohne Windows ist wie eine Schokoladentorte ohne Senf.
|
|
jaenicke
      
Beiträge: 19345
Erhaltene Danke: 1753
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 01.10.07 15:43
Stefan.Buchholtz hat folgendes geschrieben: | | Nein, das ist meines Wissens nicht so - with wertet den Ausdruck nur einmal aus und arbeitet mit einer verborgenen Variable. Einen Performance-Nachteil gegenüber einer expliziten Variable zum Zwischenspeichern bringt das nicht. |
 Würde ja auch keinen Sinn machen, with xy.Create do begin..end geht ja auch...
|
|
Wonko 
      
Beiträge: 69
|
Verfasst: Mo 01.10.07 15:53
Vielen Dank Euch beiden!
Auf die, ja doch simple, Erklärung hätte ich auch selber kommen können/sollen.
Werde mir die Sache mit den Variablen bzw. Listen mal durch den Kopf gehen lassen.
_________________ "Read the directions, even if you don't follow them.", Mary Schmich
|
|
|