Block in Hülle und Fülle verwenden?

8

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:

%Vor%

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:

%Vor%

Die andere Option besteht nicht darin, using Blöcke zu verwenden und direkt try-catch Blöcke zu implementieren. Das würde so aussehen:

%Vor%

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?

    
InBetween 03.06.2011, 12:46
quelle

3 Antworten

16

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.

    
Jon Egerton 03.06.2011, 12:50
quelle
7

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:

%Vor%

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.

%Vor%

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:

%Vor%

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.

    
casperOne 03.06.2011 12:51
quelle
1

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%     
Mark Heath 03.06.2011 12:55
quelle

Tags und Links