При наличии провала в памяти сегодня, нуждайтесь в руке, проверяющей, что моя логика не является fubar'ed.
Традиционно я сделал бы файл i/o подобный этому:
FileStream fs = null; // So it's visible in the finally block
try
{
fs = File.Open("Foo.txt", FileMode.Open);
/// Do Stuff
}
catch(IOException)
{
/// Handle Stuff
}
finally
{
if (fs != null)
fs.Close();
}
Однако это не очень изящно.
Идеально я хотел бы использовать using
блок для избавления от filestream, когда я сделан однако я не уверен в совместных действиях между использованием и попыткой/выгодой.
Это - то, как я хотел бы реализовать вышеупомянутое:
try
{
using(FileStream fs = File.Open("Foo.txt", FileMode.Open))
{
/// Do Stuff
}
}
catch(Exception)
{
/// Handle Stuff
}
Однако я волнуюсь, что преждевременный выход (через вызванную исключительную ситуацию) из блока использования не может позволить блоку использования завершать выполнение, и вымыться это - объект. Я просто параноик, или это на самом деле проложит себе путь, я предназначаю это к?
Вы просто параноик и он будет работать так, как вы предполагали:)
Оператор using эквивалентен блоку try / finally, независимо от того, находится ли он внутри try / catch или нет.
Итак, ваш код похож на:
try
{
FileStream fs = null;
try
{
fs = File.Open("Foo.txt", FileMode.Open);
// Do stuff
}
finally
{
if (fs != null)
{
fs.Dispose();
}
}
}
catch(Exception)
{
/// Handle Stuff
}
Не волнуйтесь, он очистится, как и ожидалось, и чище, чем исходный.
На самом деле, гораздо более распространено использование оператора try / finally, также известного как using, в вашей бизнес-логике и try / catch в обработчике верхнего уровня на уровне пользовательского интерфейса или на границе физического уровня. Что-то вроде:
try
{
DoStuffWithFile("foo.txt");
}
catch(Exception ex)
{
...
}
и
public void DoStuffWithFile(string fileName)
{
using(FileStream fs = File.Open(fileName,...))
{
// Do Stuff
}
}
try
{
FileStream fs = null;
try
{
fs = File.Open("Foo.txt", FileMode.Open);
}
finally
{
fs.Dispose();
}
}
catch(Exception)
{
/// Handle Stuff
}
второй фрагмент кода транслируется в этот
Блок using будет работать точно так же, как вы вводите переведенный блок using, на самом деле просто
try
{
FileStream fs = null;
try
{
fs = File.Open("Foo.txt", FileMode.Open))
//Do Stuff
}
finally
{
if(fs != null)
fs.Dispose();
}
}
catch(Exception)
{
/// Handle Stuff
}
Вам не нужна попробуйте .. наконец
, если у вас есть using ()
. Они выполняют одну и ту же операцию.
Если вы не уверены, укажите Reflector на вашей сборке и сравните сгенерированный код.
Это будет работать - внутри оператор using компилируется так же, как и блок try-finally