2016-01-07 28 views
6

Domanda rapida sull'utilizzo di dispositivi usa e getta nidificati in una singola istruzione "using": Devo scrivere ogni istruzione usa e getta di un disposable o posso inserirli in uno solo? Esempio:Nesting 'IDisposable's in a single' using 'statement

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); 
} 

vs.

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); 
} 

Solo curioso se quando il blocco è fatto di esecuzione, il FileStream senza nome da "myFile.txt" viene ripulito perché è nel usando dichiarazione con la GZipStream o se rimane aperto e deve essere ripulito qualche volta dopo.

Modifica: Giusto per essere chiari, non sto chiedendo di annidare usando le istruzioni. Sto chiedendo se un IDisposable creato all'interno dell'istruzione 'using' di un altro IDisposable sarà eliminato alla fine del blocco. Qualsiasi spiegazione sul perché o perché no sarebbe apprezzata.

+0

Possibile duplicato di [Nested using statements in C#] (http://stackoverflow.com/questions/1329739/nested-using-statements-in-c-sharp) – Joshua

+3

Se il costruttore FileStream ha esito positivo ma il costruttore GZipStream non riesce , bene, oops. –

+1

Forse vale la pena creare un insieme molto semplice di classi fittizie che implementano IDisposable e guarda cosa succede nel debugger? – DanS

risposta

6

Dipende dal costruttore, GZipStream dispone del torrente avete passato quando si smaltisce meno che non si utilizzi uno dei overloads che prende in un bool e si passa a trueleaveOpen.

Tuttavia si corre il rischio di farlo. Se GZipStream genera un ArgumentException perché la proprietà CanRead dello stream è false, il flusso di dati in entrata non viene eliminato.

Personalmente preferisco non dipendere da "qualcosa che non va storto" e invece di solito codice in modo difensivo e utilizzare la versione di dichiarazione 3.


Edit: Giusto per essere chiari, non sto chiedendo di nidificazione utilizzando le istruzioni. Sto chiedendo se un IDisposable che è stato creato all'interno di un'altra istruzione 'using' di un altro IDisposable sarà eliminato alla fine del blocco. Qualsiasi spiegazione sul perché o perché no sarebbe apprezzata.

Se questa è la vostra domanda, allora la risposta è: no, solo l'oggetto dichiarato che è stato assegnato a (using var whatever = ...) saranno smaltiti, tutti gli altri oggetti creati dipendono il codice di qualsiasi oggetto "esterno" è da implementare per "chiamare a catena" i metodi Dispose().

1

La risposta semplice è no - è necessario avvolgere ogni oggetto.

3

se quando il blocco è fatto di esecuzione, il FileStream senza nome da "myFile.txt" viene ripulito perché è nel l'istruzione using con il GZipStream

Anche quando entrambi i costruttori successo, dipende ancora sul design della classe 'possedere'. Un StreamReader chiuderà il suo BaseStream ma molte altre classi no.

Non si desidera che il codice dipenda da tale torbidezza e sia soggetto a modifiche dei dettagli.