Wenn ich eine Formularmethode schreibe, bei der ein lokaler Parameter width heisst, dann meckert der Compiler, daß dieser Bezeichner schon existiert.
Allerdings nur dann, wenn ich im Modus objfpc compiliere. Im Modus Delphi meckert er nicht,
liefert aber innerhalb der aufgerufenen Methode nicht den übergebenen Inhalt sondern den Inhalt von Form.width.
Delphi macht das nicht.
Kann man das als Bug betrachten?
Hier ein fertiges Beispiel.
Lokaler Parameter vs. Formeigenschaft?
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1436
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Lokaler Parameter vs. Formeigenschaft?
- Dateianhänge
-
- project1.zip
- (139.3 KiB) 78-mal heruntergeladen
Re: Lokaler Parameter vs. Formeigenschaft?
Ich meine das Problem liegt eher darin, dass der Canvas von Lazarus, im Unterschied zu dem von Delphi, eine Property Width besitzt und du ein "with PaintBox1.Canvas" im Code hast. Wenn ich mich nicht täusche, wiegt das "with" stärker als ein Funktionsparameter. Daher bezieht sich das "width" in dem "with" Block auf die Width des Paintbox.Canvas, die identisch ist mit der Width der Paintbox und, weil Paintbox client-align-t ist, mit der Width des Formulars (eigentlich ClientWidth, aber das ist bei LCL-Formularen dasselbe).
Generell: Ich meide den Delphi-Modus, wenn es geht, und Funktionsargumente bekommen ein "A" (für "Argument") vorangesetzt - damit geht man den meistern dieser Problem aus dem Weg. Und auch der "with" Anweisung gehe ich aus dem Weg, solange die Programmzeilen nicht zu unhandlich werden.
Generell: Ich meide den Delphi-Modus, wenn es geht, und Funktionsargumente bekommen ein "A" (für "Argument") vorangesetzt - damit geht man den meistern dieser Problem aus dem Weg. Und auch der "with" Anweisung gehe ich aus dem Weg, solange die Programmzeilen nicht zu unhandlich werden.
- fliegermichl
- Lazarusforum e. V.
- Beiträge: 1436
- Registriert: Do 9. Jun 2011, 09:42
- OS, Lazarus, FPC: Lazarus Fixes FPC Stable
- CPU-Target: 32/64Bit
- Wohnort: Echzell
Re: Lokaler Parameter vs. Formeigenschaft?
Stimmt, hast Recht.
TCanvas in Delphi hat keine Property width.
Der Delphi Modus ist natürlich sehr nützlich wenn man ein großes Delphiprojekt nach Lazarus portiert.
Es sind halt solche Kleinigkeiten über die ich dabei stolpere.
TCanvas in Delphi hat keine Property width.
Der Delphi Modus ist natürlich sehr nützlich wenn man ein großes Delphiprojekt nach Lazarus portiert.
Es sind halt solche Kleinigkeiten über die ich dabei stolpere.
-
- Beiträge: 1913
- Registriert: Di 23. Sep 2014, 17:46
- OS, Lazarus, FPC: Win10 | Linux
- CPU-Target: x86_64
Re: Lokaler Parameter vs. Formeigenschaft?
Die Beobachtung von dir am Anfang stimmt allerdings schon. Der FPC hat im Modus ObjFPC striktere Shadowing Einschränkungen als im modus Delphi:
Das Kompiliert im Modus Delphi aber nicht im ObjFPC Modus.
Grundsätzlich sollte man Shadowing allerdings soweit wie Möglich sowieso vermeiden, da es sehr schnell zu Bugs führen kann. Mein lieblingsbeispiel hierfür ist das "With" statement:
Ziemlich leicht zu übersehen aber wegen dem Semikolon nach dem do, endet das with statement bereits vor dem begin-end block. Lazarus macht beim Vervollständigen vom with statement am ende ein Semikolon selbständig, somit ist es einfach das zu übersehen. Wenn man nicht aufpasst und das nicht wegmacht wenn man begin-end hinschreibt dann dann Ändert man plötzlich die Eigenschaften der Form selbst und nicht die des Buttons.
Die typische Best-Practice für für Parameter ist es Deshalb ein A davor zu setzen, z.B. wenn man mal in die LCL schaut findet man sowas in TForm:
Damit die Parameter nicht mit den Eigenschaften Left, Top Width und Height kollidieren wird statdessen ALeft, ATop, etc. geschrieben.
Das sollte man sich einfach für alle Parameter angewöhnen und man kommt nie in die Verlegenheit das man ausversehen Properties Shadowed.
Code: Alles auswählen
TTest = class
Test: Integer;
procedure Foo(Test: Integer);
end;
Grundsätzlich sollte man Shadowing allerdings soweit wie Möglich sowieso vermeiden, da es sehr schnell zu Bugs führen kann. Mein lieblingsbeispiel hierfür ist das "With" statement:
Code: Alles auswählen
procedure TForm1.Button1Click(Sender: TObject);
begin
With Sender as TButton do;
begin
Caption := 'Clicked';
Color := clRed;
end;
end;
Die typische Best-Practice für für Parameter ist es Deshalb ein A davor zu setzen, z.B. wenn man mal in die LCL schaut findet man sowas in TForm:
Code: Alles auswählen
procedure SetRestoredBounds(ALeft, ATop, AWidth, AHeight: integer; const
ADefaultPosition: Boolean = False);
Das sollte man sich einfach für alle Parameter angewöhnen und man kommt nie in die Verlegenheit das man ausversehen Properties Shadowed.