2016-01-07 4 views
6

Быстрый вопрос об использовании вложенных одноразовых ресурсов в одном выражении «using»: Должен ли я записывать инструкцию использования каждого одноразового использования или я могу вложить их в один? Пример:Вложение 'IDisposable' в одном выражении 'using'

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

против

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

Просто любопытно, если когда блок выполняется выполнение, неназванный FileStream из «Myfile.txt» очищается, потому что это в использовании заявление с GZipStream или если он остается открытым и его необходимо очистить через некоторое время после этого.

Редактировать: Чтобы быть ясным, я не спрашиваю о вложенности с помощью утверждений. Я спрашиваю, будет ли IDsposable, созданный внутри другого оператора IDisposable 'using', будет удален в конце блока. Любое объяснение причин или почему не было бы оценено.

+0

Возможный дубликат [Вложенные операторы using в C#] (http://stackoverflow.com/questions/1329739/nested-using-statements-in-c-sharp) – Joshua

+3

Если конструктор FileStream успешно завершен, но конструктор GZipStream не работает, тогда , ну, упс. –

+1

Возможно, стоит настроить очень простой набор фиктивных классов, которые реализуют IDisposable и смотреть, что происходит в отладчике? – DanS

ответ

6

Это зависит от конструктора, GZipStream распоряжается поток, переданным в том, когда вы избавиться от него, если вы используете один из overloads, который принимает в BOOL и проходите в true к leaveOpen.

Однако вы рискуете сделать это. Если GZipStream выбрасывает ArgumentException, так как свойство CanRead потока равно false переданное в потоке не удаляется.

Лично я предпочитаю не зависеть от «чего-то не так» и вместо этого обычно защищать код и использовать версию 3-го утверждения.


Edit: Просто чтобы быть ясно, я не спрашиваю о вложенности с помощью заявления. Я спрашиваю, будет ли IDisposable, созданный внутри , другой оператор IDisposable 'using' будет удален в конце блока. Любое объяснение причин или почему не было бы оценено.

Если это ваш вопрос, то ответ: Нет, только объект объявляется, который был назначен (using var whatever = ...) будут захоронены, любые другие объекты, создаваемые в зависимости от кода из любой «внешний» объект является для реализации «цепного вызова» Dispose().

1

Простой ответ: нет - вам нужно обернуть каждый объект.

3

если когда блок выполняется выполнение, неназванный FileStream из «Myfile.txt» очищается, потому что это в использовании заявление с GZipStream

Даже когда оба Конструкторы успеха, он по-прежнему зависит по дизайну «владеющего» класса. StreamReader закроет свой BaseStream, но многие другие классы не будут.

Вы не хотите, чтобы ваш код зависел от такого мутного и может изменить детали.