- Details
- Geschrieben von: Sebastian Jänicke
- Kategorie: Themen aus der Praxis
- Zugriffe: 17
Ich werde immer wieder gefragt, was an with denn so schlimm sei. Nun, es gibt eine ganze Reihe von Gründen, weshalb man auf die Nutzung von with verzichten sollte. Diese möchte ich hier genauer erläutern.
-
Probleme mit neuen Delphiversionen
Der folgende Code ist kein besonders sinnvoller Code. Er soll nur kurz zwei Beispiele demonstrieren. Das sah in den VirtualTrees so aus (TStringEditLink.SetBounds), was zu einem Fehler unter XE2 führte.
procedure TMyForm.Test1;
var
TargetPos: TRect;
begin
TargetPos := Rect(0, 0, 500, 500);
with TargetPos do
begin
Width := Right - Left; // bis XE MyForm.Width, ab XE2 TargetPos.Width
Height := Bottom - Top;
end;
end;
procedure TMyForm.Test2;
var
TargetPos: TRect;
Offset: Integer;
begin
TargetPos := Rect(0, 0, 0, 0);
with TargetPos do
begin
Offset := 10; // bis XE Offset (lokale Variable), ab XE2 TargetPos.Offset
Self.Left := Left + Offset;
Self.Top := Top + Offset;
end;
end;
Unter Delphi XE führt der Aufruf von Test1 und Test2 dazu, dass das Formular die Position 10/10 und die Größe 500/500 einnimmt. Unter XE2 passiert mit Test1 gar nichts mehr und Test2 lässt sich nicht mehr kompilieren.
Zur Erklärung:
Mit Delphi XE2 wurde TRect unter anderem um Width und Offset erweitert. Die Zuweisung an Width passiert daher nun in TargetPos, wo es keinen Effekt hat. Und da TargetPos nun die Methode Offset hat, verdeckt diese die lokale Variable, so dass der Code nicht mehr kompiliert werden kann.
Der zweite Fall fällt nach einem Update der Delphiversion natürlich auf. Der erste Fall jedoch bleibt ggf. unentdeckt und kann dann zu schwer lokalisierbaren Fehlern führen. Im echten Code sind die Auswirkungen ja nicht unbedingt so direkt nachvollziehbar. Und solche Änderungen können überall auftreten, so dass with ein unkalkulierbares Risiko ist.
-
Probleme beim Debuggen
procedure TMyForm.Test;
var
Demo: TPoint;
begin
with Demo do
begin
X := 42;
X := X + 1; // Haltepunkt
end;
end;
Wenn man den Wert von X wissen möchte, kann man normalerweise einfach den Mauszeiger darüber halten. Mit with geht das leider nicht. Markiert man nun den Ausdruck und drückt Strg + F7, geht das auch nicht. Man muss also manuell den Ausdruck aus with kopieren und in das Fenster zum Auswerten kopieren (oder ihn manuell ergänzen).
Dadurch wird das Debuggen unnötig umständlich.
-
Schlechtere Lesbarkeit des Codes
Man sieht nicht auf den ersten Blick, welcher Identifier zu dem Element in with gehört und welcher eigenständig ist, was die Lesbarkeit erschwert. Wenn man selbst in einem Jahr auf den Quelltext schaut oder gar jemand anderes, braucht das Verständnis des Quelltextes entsprechend länger.
Außerdem braucht man zum Verständnis des Codes immer die genauen Variablentypen, da man sonst nicht weiß, welche Elemente diese haben. Und wenn man die Elemente nicht im Kopf hat, muss man das erst recherchieren. Dadurch dauert es deutlich länger, Code zu überblicken und zu ändern.
-
Refactoring des Quelltexts
Man kann Teile des Quelltextes nicht einfach kopieren oder überarbeiten, weil man auf das with Rücksicht nehmen muss.
-
LSP und Codevervollständigung
Der LSP und damit die Codevervollständigung funktionieren mit with schlechter.