Update : Das ist eigentlich keine gute Antwort. Auf der anderen Seite ist es vielleicht eine gute Antwort, weil es ein perfektes Beispiel für den Erfolg von finally
darstellt, wo ein Entwickler (d. H. Ich) es versäumt, die Bereinigung richtig zu gewährleisten. Berücksichtigen Sie im folgenden Code das Szenario, in dem eine Ausnahme andere als SpecificException
ausgelöst wird. Dann führt das erste Beispiel noch eine Bereinigung durch, während die zweite nicht funktioniert, obwohl der Entwickler denken könnte "Ich habe die Ausnahme abgefangen und verarbeitet, also wird der nachfolgende Code sicherlich ausgeführt."
Jeder gibt Gründe dafür, try
/ finally
ohne a catch
zu verwenden. Es kann immer noch sinnvoll sein, dies mit a catch
zu tun, auch wenn Sie eine Ausnahme auslösen. Betrachten Sie den Fall *, in dem Sie einen Wert zurückgeben möchten.
Die Alternative zu obigem ohne a finally
ist (meiner Meinung nach) etwas weniger lesbar:
* Ich denke, ein besseres Beispiel von try
/ catch
/ finally
ist, wenn die Ausnahme neu geworfen wird (mit throw
, nicht throw ex
- aber das ist ein anderes Thema) im catch
-Block, und daher ist finally
notwendig, da es ohne Code nicht funktioniert, nachdem die try
/ catch
nicht ausgeführt wurde. Dies wird normalerweise mit einer using
-Anweisung auf einer IDisposable
-Ressource erreicht, aber das ist nicht immer der Fall. Manchmal ist die Bereinigung nicht speziell ein Dispose
Aufruf (oder ist mehr als nur ein Dispose
Aufruf).
Es wird fast immer zur Bereinigung verwendet, normalerweise implizit über eine using
-Anweisung:
Nun ist das nicht äquivalent zu
%Vor%weil der Code "read some stuff" eine Exception auslösen oder möglicherweise zurückgeben könnte - und wie auch immer er vervollständigt wird, möchten wir den Stream entfernen.
So finally
Blöcke sind normalerweise für eine Ressourcenbereinigung in irgendeiner Form. In C # sind sie jedoch normalerweise über eine using
-Anweisung implizit:
finally
Blöcke sind viel häufiger in Java als in C #, genau wegen der using
Anweisung. Ich schreibe sehr selten meine eigenen finally
Blöcke in C #.
Du brauchst endlich einen, denn du solltest nicht immer einen Haken haben:
%Vor% Die obige Methode erkennt keine Fehler bei der Verwendung von fs
und überlässt sie dem Aufrufer. Aber es sollte immer den Stream schließen.
Beachten Sie, dass diese Art von Code normalerweise einen using() {}
Block verwendet, aber das ist nur eine Kurzform für einen try / finally. Um abzuschließen:
Wenn Sie einen finally-Block haben, wird der Code darin beim Beenden des try garantiert ausgeführt. Wenn Sie Code außerhalb von try / catch platzieren, ist das nicht der Fall. Ein häufigeres Beispiel ist dasjenige, das mit verfügbaren Ressourcen verwendet wird, wenn Sie die using
-Anweisung verwenden.
wird zu
erweitert %Vor% Dies stellt sicher, dass alle nicht verwalteten Ressourcen entsorgt und freigegeben werden, auch im Fall einer Ausnahme während der try
.
* Beachten Sie, dass es Situationen gibt, in denen die Steuerung den Versuch nicht beendet, und der schließlich nicht ausgeführt wird. Ein einfaches Beispiel ist PowerFailureException
.
Der Code, der in den finally
-Block gesetzt wird, wird auch dann ausgeführt, wenn:
return
-Anweisungen im Block try
oder catch
catch
-Block wiederholt die Ausnahme Beispiel:
%Vor% Sie verwenden es nicht unbedingt mit Ausnahmen. Sie können try/finally
verwenden, um vor jedem return
im Block eine Bereinigung auszuführen.
Der finally-Block wird immer ausgeführt, unabhängig davon, ob ein Fehler vorliegt oder nicht. Es wird in der Regel für Reinigungszwecke verwendet.
Für Ihre Frage besteht die allgemeine Verwendung von Catch darin, den Fehler an den Aufrufer zurückzugeben. In solchen Fällen wird der Code schließlich noch ausgeführt.
Wenn im catch-Block eine Ausnahme auftritt (oder erneut ausgelöst wird), wird der Code nach dem catch nicht ausgeführt - im Gegensatz dazu wird der Code in einem finally noch ausgeführt.
Außerdem wird Code innerhalb von finally sogar ausgeführt, wenn die Methode mit return beendet wird.
Schließlich ist es besonders praktisch, wenn Sie mit externen Ressourcen wie Dateien arbeiten, die geschlossen werden müssen:
%Vor%Beachten Sie jedoch, dass Sie in diesem Beispiel auch mit verwenden können:
%Vor%Zum Beispiel während des Prozesses können Sie WinForm ... deaktivieren
%Vor%