![]() |
Automatisches Verlassen einer Funktion bei Result := False;
Automatisches Verlassen einer Funktion bei Result := False;
Wer viel mit Algorithmen arbeitet, kennt das Problem: Jedesmal, wenn man in einer Funktion Result auf False setzt, will man eigentlich, dass die Funktion auch gleich mit Exit beendet wird - dazu sind zwei Zeilen nötig. Wenn man das oft macht, kann da einen Code auch verunstalten und unübersichtlich machen. Die Idee bei diesem Tipp: statt Result auf False zu setzen, löst man künstlich eine Exception aus, die mit try..except abgefangen wird. Beim Abfangen wird Result auf False gesetzt und die Funktion verlassen. Das kann viele Zeilen Code sparen. Dazu muss aber gesagt werden, dass Exceptions eine recht zeitspielige (und damit auich kostspielige ;-)) Angelegenheit sind, man sollte das also nicht unbedingt im Suchalgorithmus oder in der Datenbankquery anweden. So sieht das ganze in der Praxis dann aus: Zuerst deklariert man eine eigene Exception, die dann ausgelöst werden soll:
Code:
Jetzt kann man das ganze im Code anwenden:
type
EResultFalse = class(Exception);
Code:
Bei Create ist ein Parameter nötig, der die Message ausgeben würde, die erscheint, wenn die Exception nicht abgefangen würde. Man sollte übrigens unter Tools|Debugger Options|Language Exceptions das Anhalten bei Delphi-Exceptions ausschalten, ansonsten bekommt man in der IDE jedes mal, wenn Result auf False gestellt wird, eine Exception gegen den Kopf geschleudert...
function Test(h: THandle): Boolean;
begin try if (h = INVALID_HANDLE_VALUE) then raise EResultFalse.Create(''); // Exception auslösen except on EResultFalse do begin Result := False; Exit; end; end; end; Viel Spaß, d3g |
Ich will dich ja nicht kritisieren, aber ich mache das setzen von Result:=False+Exit; so:
Code:
Und ich findes es sehr Hilfreich, wenn Delphi die Exception für mich abfängt, da ich somit genau weiß, in welcher Funktion/Bereich die Exception ausgelöst wurde und somit schneller den Fehler finde, als wenn ich erst das ganze Programm debuggen muss.
function Test(h: THandle): Boolean;
begin Result := False; if (h = INVALID_HANDLE_VALUE) then Exit; // ... Result := True; end; Und Exceptions sind nicht dazu da einen Algorithmus zu unterstützen, sondern um Fehler in ihm abzufangen. Sonst könnte man gleich wieder zum GOTO zurückkehren. |
Hi jbg,
du hast ganz recht, allerdings ist es manchmal sinnvoller, Result am Funktionsanfang auf True und nicht auf False zu stellen. Das umzuschreiben würde einen Code teilweise unverständlich und umständlich machen, deshalb mache ich es so. Was das goto angeht: Schön ist es nicht, aber manchmal doch recht sinnvoll. Der try..except..end-Block ist, das musst du zugeben, auch sehr viel eleganter also goto:
Code:
statt
function Test(h: THandle): Boolean;
begin try if (h = INVALID_HANDLE_VALUE) then raise EResultFalse.Create(''); // Exception auslösen except on EResultFalse do begin Result := False; Exit; end; end; end;
Code:
Aber da die Kritik an dieser Methode immer größer wird: Ich werde mich nicht daran festbeißen, ich bestehe absolut nicht darauf, ihn durchzubringen.
function Test(h: THandle): Boolean;
label resultfalse, toend; begin Result := False; if (h = INVALID_HANDLE_VALUE) then goto resultfalse; // ... goto toend; resultfalse: Result := True; toend: // ... end; MfG, d3g |
Moin Zusammen,
in diesem speziellen Falle ginge es sogar so sehr gut:
Code:
function Test(h: THandle): Boolean;
begin Result := h <> INVALID_HANDLE_VALUE; end; |
Hallo Christian,
ja, in diesem Fall, aber es geht hier doch eher um kompliziertere Funktionen :?: MfG, d3g |
Moin d3g,
ist schon klar ;-) Ich für meinen Teil bevorzuge allerdings auch jbg's Vorgehensweise: Erst einmal Result initialisieren, und dann ggf. einfach mit Exit raus. Das auch wenn es sich nicht um boolsche Results handelt. In diesem Falle wird dann einfach nach jedem Exit Result mit dem nächstwahrscheinlichen Wert gefüllt. Dadurch erspare ich mir dann auch tiefere Verschachtelungen. Ist natürlich auch Geschmackssache. |
Hallo!
Weiteres Argument gegen das Auslösen einer Exception: Try-Blöcke sollen langsam sein, so habe ich mal irgendwo aufgeschnappt. Man sollte ihren Einsatz also auf kritische Stellen wie Speicherfreigabe etc. reduzieren. Cu, :D Udontknow |
Zitat:
d3g |
Hallo,
ich finde das die Exception den Code nicht nur langsamer, sondern auch unübersichtlicher macht. Wenn Du nur eine Zeile willst, warum schreibst Du dann nicht:
Code:
Aber das ist nur meine bescheidene Meinung und Geschmackssache.
...
Result := False; Exit; // Abbruch ... Ich persönlich bevorzuge jbg's Vorschlag. (Mache ich schon ewig so und hatte noch nie Probleme damit.) Aber wegen so einer Kleinigkeit sollte man sich nicht streiten. Es gibt ja schließlich auch Schreibfaule die statt False einfach 1=2 schreiben, weils kürzer ist (result:=1=2;Exit;) :D mfg MaBuSE |
Hi MaBuSE,
jbg's lösung ist nicht universell, sondern nur bei sich wiederholenden if-Abrfragen zu gebaruachen. Und ob nun eine Zeile oder zwei ist mir auch egal. Es geht nur um diese begin..end-Konstrukte bei Schleifen und if-Abrfragen, die den Quellcode aufblähen. MfG, d3g PS. Ich frage mich, warum der Thread eigentlich nach "Tutorials" verschoben wurde... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:23 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