2016-01-07 16 views
6

Schnelle Frage zur Verwendung verschachtelter Disposables in einer einzigen' using'-Anweisung: Soll ich die using-Anweisung jedes Disposables ausschreiben oder kann ich sie verschachteln? Beispiel:Verschachteln von IDisposables in einer einzigen 'using'-Anweisung

using(FileStream inFile = new FileStream("myFile.txt", FileMode.Open)) 
using(GZipStream gzip = new GZipStream(inFile, CompressionMode.Decompress)) 
using(FileStream outFile = new FileStream("myNewFile.txt", FileMode.CreateNew)) 
{ 
    gzip.CopyTo(outstream); 
} 

gegen

using(GZipStream gzip = new GZipStream(new FileStream("myFile.txt", FileMode.Open), CompressionMode.Decompress)) 
using(FileStream outFile = new FileStream("myNewFile.txt", FileMode.CreateNew)) 
{ 
    gzip.CopyTo(outstream); 
} 

nur neugierig, ob, wenn der Block ausgeführt wird getan wird, wird die unbenannte Filestream von „MYFILE.TXT“ gereinigt, weil es mit dem GZipStream in der using-Anweisung ist oder wenn es offen bleibt und danach wieder aufgeräumt werden muss.

Bearbeiten: Nur um klar zu sein, ich frage nicht über Verschachtelung mit Anweisungen. Ich frage, ob ein IDisposable, das in einer 'using'-Anweisung eines anderen IDisposables erstellt wird, am Ende der Sperre entsorgt wird. Jede Erklärung warum oder warum nicht, würde geschätzt werden.

+0

Mögliches Duplikat von [Nested using-Anweisungen in C#] (http://stackoverflow.com/questions/1329739/nested-using-statements-in-c-sharp) – Joshua

+3

Wenn der FileStream-Konstruktor erfolgreich ist, aber der GZipStream-Konstruktor fehlschlägt naja, oops. –

+1

Vielleicht lohnt es sich, eine sehr einfache Gruppe von Dummy-Klassen einzurichten, die IDisposable implementieren und beobachten, was im Debugger passiert? – DanS

Antwort

6

Es hängt von der Konstruktor GZipStream verfügt über den Stream Sie in übergeben, wenn Sie darüber verfügen, wenn Sie eine der overloads verwenden, die in einem Bool dauert und Sie passieren in true zu leaveOpen.

Allerdings laufen Sie ein Risiko dabei. Wenn GZipStream eine ArgumentException auslöst, weil die CanRead Eigenschaft des Streams false ist, wird der übergebene Stream nicht entsorgt.

Persönlich bin ich eher nicht auf "etwas nicht schief gelaufen" und stattdessen in der Regel defensiv Code und verwenden Sie die 3-Anweisung-Version.


Edit: Nur klar zu sein, ich bitte nicht über die Verwendung von Aussagen nisten. Ich frage, ob ein IDisposable, das innerhalb eines anderen IDisposable 'using' Anweisung erstellt wird oder nicht, am Ende des Blocks entsorgt werden. Jede Erklärung warum oder warum nicht, würde geschätzt werden.

Wenn das Ihre Frage dann ist die Antwort: Nein, erklärt nur das Objekt, das zu (using var whatever = ...) zugewiesen wurde entsorgt werden, erstellt alle anderen Objekte sind auf dem Code abhängig von was auch immer der „äußeren“ Objekt implementiert werden, um die Methoden Dispose() zu "ketten".

1

Einfache Antwort ist nein - Sie müssen jedes Objekt umhüllen.

3

wenn, wenn der Block ausgeführt wird getan wird, wird die unbenannte Filestream von „MYFILE.TXT“ gereinigt, weil es mit dem GZipStream in der using-Anweisung ist

Selbst wenn beide Konstrukteure erfolgreich zu sein, es hängt immer noch auf das Design der "besitzenden" Klasse. Ein StreamReader schließt seinen BaseStream, viele andere Klassen jedoch nicht.

Sie möchten nicht, dass Ihr Code von solch trüben und leicht zu ändernden Details abhängt.