Ich hätte gerne Ihre Meinung zu folgendem Thema:
Stellen Sie sich vor, wir haben eine Methode, die dafür verantwortlich ist, einen bestimmten Zweck zu erreichen, aber dafür benötigt sie eine große Anzahl von Objekten mit lokalem Bereich, von denen viele IDisposable
implementieren.
MS-Codierungsstandards sagen, dass wenn lokale IDisposable
-Objekte verwendet werden, die den Umfang der Methode nicht "überleben" müssen (werden nicht zurückgegeben oder werden nicht den Zustandsinformationen von zum Beispiel längerlebigen object
zugewiesen) Sie sollten das using
-Konstrukt verwenden.
Das Problem ist, dass Sie in einigen Situationen eine verschachtelte "Hölle" von using
blocks bekommen können:
Sie können dies irgendwie abschwächen, wenn einige der von Ihnen verwendeten Objekte von einer gemeinsamen Basis abgeleitet werden oder ein gemeinsames interface
implementiert wird, das IDisposable
implementiert. Dies kostet natürlich die Kosten, die genannten Objekte zu werfen, wann immer Sie den wahren Typ des Objekts benötigen. Manchmal kann dies lebensfähig sein, solange die Menge des Gusses nicht außer Kontrolle gerät:
Die andere Option besteht nicht darin, using
Blöcke zu verwenden und direkt try-catch
Blöcke zu implementieren. Das würde so aussehen:
Lustig ist, dass VS Code Analyzer diesen Code als "falsch" kennzeichnet. Es wird Sie darüber informieren, dass nicht alle möglichen Ausführungspfade sicherstellen, dass alle verfügbaren Objekte entsorgt werden, bevor sie den Geltungsbereich verlassen. Ich kann das nur sehen, wenn ein Gegenstand wirft, während er entsorgt, was meiner Meinung nach nie passieren sollte, und wenn, dann ist das normalerweise ein Zeichen dafür, dass etwas wirklich durcheinander ist und du wahrscheinlich besser bist, so schnell und anmutig zu enden wie du kann von deiner gesamten App aus.
Die Frage ist also: Welchen Ansatz magst du besser? Ist es immer vorzuziehen, verschachtelte using
Blöcke zu verwenden, egal wie viele, oder, ab einer bestimmten Grenze, ist es besser, try-catch
block zu verwenden?
Sie benötigen die geschweiften Klammern nicht, wenn es nur eine Anweisung gibt, zum Beispiel:
%Vor%Dies hängt jedoch davon ab, dass nichts anderes in den äußeren Blöcken passiert.
Ich glaube, Sie vergessen, dass die using
-Anweisung (wie viele andere) nicht notwendigerweise einen Codeblock erfordert, sondern eine einzelne Anweisung sein kann. Ihr erstes Beispiel kann wie folgt geschrieben werden:
Ich denke, das erleichtert das Problem enorm. Beachten Sie, dass es nicht hilfreich ist, wenn Sie zwischen dem Aufruf der Instanzen, die IDisposable
implementieren, etwas tun müssen.
Ich gehe sogar so weit, andere Blöcke zu verschachteln, die Sinn ergeben. foreach
ist ein Beispiel.
Es sollte beachtet werden, dass der VS-Code-Analysator korrekt ist, wenn er Ihnen mitteilt, dass dies nicht korrekt ist:
%Vor% Wenn Sie using
übereinander gestapelt verwenden, verschachtelt es sie in mehreren try
/ finally
-Blöcken, etwa so:
Wenn in Ihrem Beispiel eine Ausnahme ausgelöst wird, wenn disposableA.Dispose
ausgeführt wird, werden disposableB
und disposableC
nicht entsorgt (der finally
-Block wird beendet), wenn ein Fehler ausgelöst wird disposableB
wird aufgerufen, dann wird disposableC
nicht geschlossen usw.
Das einzige wirkliche "Problem" mit Ihrem ersten Codebeispiel ist die tiefe Verschachtelung, die das Lesen und Pflegen von Code erschweren kann. Als eine Alternative zu den anderen Antworten, die vorschlagen, dass Sie die geschweiften Klammern einfach weglassen, können Sie das auch umgehen, indem Sie den am tiefsten verschachtelten Code in eine separate Funktion umwandeln. Dies unterscheidet die Bedenken, Ihre wegwerfbaren Objekte zu erstellen und zu entsorgen, sie tatsächlich zu verwenden.
%Vor%Tags und Links c# code-analysis code-design