Ich habe jahrelang Try-Catch / Except-finally-Varianten in vielen Sprachen verwendet. Heute hat mich jemand gefragt, worum es bei Final geht, und ich konnte nicht antworten.
Grundsätzlich, warum sollten Sie eine Anweisung endgültig einfügen, anstatt sie nur nach dem gesamten Try-Catch-Block einzufügen? Oder mit anderen Worten, gibt es einen Unterschied zwischen den folgenden Codeblöcken:
try{ //a}
catch {//b}
finally {//c}
try{//a}
catch{//b}
//c
EDIT:
PEOPLE, ich weiß, was endlich funktioniert, ich benutze es schon seit Ewigkeiten, aber meine Frage ist, dass das Einfügen //c
im obigen Beispiel endgültig überflüssig erscheint, nicht wahr?
return
dietry/catch
Anweisung eine Anweisung enthält. Ohne dieses Verständnisfinally
scheint eine Klausel ziemlich trivial zu sein, wenn man weiß, dass acatch all
im Wesentlichen dietry/catch
Ausführung des Codes nach dem Block unabhängig von einer Ausnahme ermöglicht. Vielen Dank, @supercat!finally
als ohne.Schließlich wird der Block auch dann ausgeführt, wenn im try-Block eine Ausnahme ausgelöst wird. Wenn Sie beispielsweise zuvor einen Stream geöffnet haben, möchten Sie diesen Stream möglicherweise schließen, entweder wird eine Ausnahme ausgelöst oder nicht. Schließlich ist Block für ein solches Problem nützlich.
quelle
finally
ist ein syntaktischer Zucker, um das DRY-Prinzip imtry-catch
Muster zuzulassen . Eine Ausnahme wird normalerweise ausgelöst, wenn der Bibliothekscode nicht genügend Informationen enthält, um einen bestimmten Status zu verarbeiten, und der Clientcode ihn lösen soll. Wenn Sie keine Trennung zwischen Bibliothek und Client-Code haben, können Sie alles mitif
statt behandelntry
.Sehen wir uns eine Standardsituation ohne an
finally
:Im obigen Snippet wiederholen Sie
freeResources()
: Dies können mehrere Anweisungen sein, die Sie wiederholen müssen. Dieser Geruch undfinally
Block ist die Lösung für sauberen Code:Lassen Sie uns drei Abstraktionsebenen realisieren:
allocateResources()
Funktion bereitstelltmyFunction
, der A1 verbrauchtmyFunction
im Try-Catch-Block verbraucht wird :Nun wollen wir sehen, was passieren kann:
allocateResources()
wir A1 einwerfen, wissen wir nicht, wie wir in A2 damit umgehen sollen (A2-Code kann in einer konsolenfreien Umgebung ausgeführt werden), daher verschieben wir die Situation auf A3, ohne weiteren Code hinzuzufügen. Wenn hier eine Ausnahme ausgelöst wird, wird der finally-Block nicht ausgeführt , da an diesenfinally
gebunden ist,try
der nicht eingegeben wurde.somethingBadHappens
in try - Block, die Stapel Abwicklungen bis A3 , wo die Situation gehandhabt wird , aber bevor esfinally
wird Block ausgeführt , so dass wir es nicht brauchen zu wiederholen , wenn keine Ausnahmen passieren.finally
wircatch
Block hinzufügen und versuchen können, einige mögliche Ausnahmen von A1 zu lösen, die in aufrufendenr.doSomething
Methoden auftreten können. Normalerweise möchten wir Ausnahmen so schnell wie möglich behandeln, um den Client-Code (A3) für Client-Codierer komfortabler zu gestalten.happyFunction()
wird nur ausgeführt, wenn nichtsmyFunction()
hineingeworfen wird (innerhalb oder außerhalb destry
Blocks).Wie @supercat hervorhebt, wird der
finally
Block auch ausgeführt, wenn dertry
Block über return beendet wird. Ich schlage vor, Sie vermeiden diese schlechte Angewohnheit und haben nur eine Rückkehr in jeder Funktion (möglicherweise gibt es einige früh am Anfang der Funktionen). Die Gründe für Single-Return-Funktionen sind:Der Grund für mehrere Rückgaben besteht darin, viele verschachtelte Wenns zu vermeiden, aber es gibt andere Techniken, um dies zu lösen.
Exception
s sind eine Ausnahme in dieser Regel.quelle
Finally
Stellen Sie sicher, dass Ihr Code ausgeführt wird, auch wenn Sie eine Ausnahme erhalten.Der finally-Block ist nützlich, um alle im try-Block zugewiesenen Ressourcen zu bereinigen und Code auszuführen, der ausgeführt werden muss, auch wenn eine Ausnahme vorliegt
http://msdn.microsoft.com/en-us/library/zwc8s4fz(v=vs.80).aspx
quelle
//c
wird ausgeführt, oder?