![]() |
AW: "FinalllyExit" gewünscht
Zitat:
Du nimmst wirklich die 2.Variante? :shock:
Delphi-Quellcode:
// Total schlecht lesbarer und unsauberer Code mit EXIt
For i:=1 to N Do For j := 1 to M Do Begin If Bla[i,j].HasInvalidData() Then Exit; Bla[i,j].Process(); ... End; ... // ... // Suupersaubere Implementierung ohne EXIT. Toll! i := 1; Aborted := False; While (i <= N) and not Aborted Do Begin j := 1; While (j <= M) and Not Aborted Do Begin If Bla[i,j].HasInvalidData() Then Aborted := True Else Begin Bla[i,j].Process(); ... Inc(J) End; End; Inc(i); End; |
AW: "FinalllyExit" gewünscht
Zitat:
|
AW: "FinalllyExit" gewünscht
Zitat:
|
AW: "FinalllyExit" gewünscht
|
AW: "FinalllyExit" gewünscht
Im Prinzip sind das alles die selben Funktionalitäten
> "Abbrechen" aka unterbrechen des linearen Programmablaufs If/Case > überspringen von Befehlen Continue > einen Schleifendurchgang abbrechen Break > ganze Schleife abbrechen Exit > Funktion verlassen Raise (Exception) > Thread beenden (es sei denn die Exception wird abgefangen > Try-Except) Halt > Programm sofort beenden (ist voll unsauber und eher für schwerwiegende Poblembehandlungen geeignet) (Goto könnte man bei mehreren dieser Punkte dazuschreiben) |
AW: "FinalllyExit" gewünscht
Zitat:
Und nur, um es nochmal zu betonen, ich sage nicht, man darf das auf keinen Fall niemalsnich verwenden. Aber bereits das Code Beispiel im TE Post zeigte, dass dort Exit mal total falsch plaziert war. Man sollte die Verwendung auf ein absolutes Minumum reduzieren und nicht dort, wo man einfach nur nen Boolschen Ausdruck negieren könnte, nen Exit reindonnern. |
AW: "FinalllyExit" gewünscht
Die Existenz derer sagt, so wie du es schon angedeutet hast, nichts über ihr Nutzen (nützlich, gut, böse?) aus.
Es liegt alles am Programmierer. Eigentlich sind wir hier alle in eine Tangente abgedriftet. Wäre nett, wenn man die Diskussion fortsetzen will, nen neuen Thread zu eröffnen! |
AW: "FinalllyExit" gewünscht
Liste der Anhänge anzeigen (Anzahl: 2)
Zitat:
An den try-Blöcken stört mich die schlechte Debugbarkeit. Gerade habe ich einen Fehler gefunden, der in einer aufgerufenen Funktion auftrat. Durch den sch... try-Block war der schlechter lokalisierbar. Ich mag die Dinger nicht und halte sie für wesentlich überschätzt. Wenn man sie konsequent nutzen will, müsste man quasi jeden Befehl in einen try-Block kapseln.
Delphi-Quellcode:
Was aber, wenn schon TA.Create fehl schlägt???
A:=TA.Create;
B:=TB.Create; try ... finally A.Free; B.Free; end; Also müsste man dutzende try-Blöcke ineinander schachteln, um wirklich sicher zu sein? Ich halte das für Unsinn. In meinem Testprojekt kann man sehen, dass "end(normal)" nur in einem Fall aufgerufen wird. Was ist aber bei 2 verschachtelten oder aufeinander folgenden try-Blöcken? Ich halte ein Standardlabel "FinallyExit" für sehr sinnvoll, das einfach IMMER vor dem Verlassen einer Funktion/Prozedur angesprungen wird, egal was vorher auch immer passiert ist. Sehr schwierig sollte das nicht lösbar sein, da ja weitestgehend nur die Exit-Sprungadresse geändert werden müsste. PS: Das mit einem selbst definierten Label zu testen, wäre etwas umständlich, da man Exit(VALUE) so nicht (mit einer Anweisung) simulieren kann.
Delphi-Quellcode:
unit fTestFinallyExit;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; type TFormTestFinallyExit = class(TForm) ButtonTest: TButton; Memo: TMemo; RadioGroupMode: TRadioGroup; procedure RadioGroupModeClick(Sender: TObject); private { Private-Deklarationen } public function Test: String; end; var FormTestFinallyExit: TFormTestFinallyExit; implementation {$R *.dfm} procedure TFormTestFinallyExit.RadioGroupModeClick(Sender: TObject); begin Memo.Lines.Add('-----' + RadioGroupMode.Items[RadioGroupMode.ItemIndex] + '-----'); Memo.Lines.Add(Test); Memo.Lines.Add(''); end; function TFormTestFinallyExit.Test: String; var S: String; I: Integer; procedure Add(SA: String); begin S := S + SA + #13#10; end; begin Result := 'nix'; S := ''; I := 0; Add('begin'); if RadioGroupMode.ItemIndex = 1 then begin Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]); Exit; end; if RadioGroupMode.ItemIndex = 2 then begin Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]); Exit('#'); end; if RadioGroupMode.ItemIndex = 3 then begin Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]); Add(IntToStr(1 div I)); end; try Add(' try'); if RadioGroupMode.ItemIndex = 4 then begin Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]); Exit; end; if RadioGroupMode.ItemIndex = 5 then begin Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]); Exit(' #'); end; if RadioGroupMode.ItemIndex = 6 then begin Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]); Add(IntToStr(1 div I)); // springt in finally und dann Exit ohne Result-Zuweisung end; Add(' ok'); finally Add(' finally'); Add('end(finally)'); Result := S; end; Add('end(normal)'); Result := S; end; end. |
AW: "FinalllyExit" gewünscht
Zitat:
Delphi-Quellcode:
Also worum gehts hier eigentlich. Alles da, was man braucht. Und deine tolle Idee ist nichts anderes und hat dann auch die selben Nachteile, die du hier vielleicht aufführen wirst.
begin
try // hier kommt alles rein finally // und das hier wird vor dem Verlassen ausgeführt, egal, was vorher war. end; end; Dabei gibt es gar keine Nachteile. |
AW: "FinalllyExit" gewünscht
Ich sehe einfach nicht was der Vorteil von deinem FinallyExit sein soll. Was ist der Unterschied, ob ich schreibe
Delphi-Quellcode:
oder
procedure Foobar;
begin try {…} if foo=bar then Exit; {…} finally ShowMessage('foobar end') end; end;
Delphi-Quellcode:
?
procedure Foobar;
begin {…} if foo=bar then Exit; {…} FinallyExit: ShowMessage('foobar end') end; Der einzige Unterschied, den ich sehe, ist, dass in letzterem Fall eine Zeile und eine Verschachtelung spare; aber dafür kommt ein zusätzliches, redundantes Sprachfeature hinzu. Zitat:
Delphi-Quellcode:
Das Tolle an Free ist nämlich, dass erst geprüft wird, ob self nil ist:
A := nil;
B := nil; try A := TA.Create; B := TB.Create; finally A.Free; B.Free; end;
Delphi-Quellcode:
Abgesehen davon löst dein FinallyExit das von dir angesprochene Problem auch nicht.
procedure TObject.Free;
begin if Assigned(self) then Destroy; end; Bezüglich deines Codebeispiels: Wieso nicht einfach so?
Delphi-Quellcode:
oder so:
function TFormTestFinallyExit.Test: String;
{…} begin Result := 'nix'; S := ''; I := 0; Add('begin'); {…} try Add(' try'); {…} if RadioGroupMode.ItemIndex = 6 then begin Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]); Add(IntToStr(1 div I)); end; Add(' ok'); finally Add(' finally'); Add('end(finally)'); Result := S; // redundant Add('end(normal)'); Result := S; end; end;
Delphi-Quellcode:
function TFormTestFinallyExit.Test: String;
{…} begin try Result := 'nix'; S := ''; I := 0; Add('begin'); {…} try Add(' try'); {…} if RadioGroupMode.ItemIndex = 6 then begin Add(RadioGroupMode.Items[RadioGroupMode.ItemIndex]); Add(IntToStr(1 div I)); end; Add(' ok'); finally Add(' finally'); Add('end(finally)'); Result := S; // redundant end; finally Add('end(normal)'); Result := S; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:55 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz