C# "Использование" Синтаксис
Ловит ли использование исключение или выбрасывает его? т.е.
using (StreamReader rdr = File.OpenText("file.txt"))
{
//do stuff
}
Если потоковый ридер генерирует исключение, перехватывается ли он с помощью или генерируется, чтобы вызывающая функция могла его обработать?
11 ответов
Использование операторов не есть исключения.
Все, что делает "Using" - это помещает ваш объект в блок using и автоматически вызывает Dispose() для объекта, когда он покидает блок.
Однако, есть ошибка, если поток принудительно прерывается внешним источником, возможно, что Dispose никогда не будет вызван.
Когда вы видите оператор использования, подумайте об этом коде:
StreadReader rdr = null;
try
{
rdr = File.OpenText("file.txt");
//do stuff
}
finally
{
if (rdr != null)
rdr.Dispose();
}
Таким образом, реальный ответ заключается в том, что он ничего не делает, за исключением того, что он добавлен в тело блока using. Он не справляется с этим или не отбрасывает его.
using
позволяет исключению прокипеть. Он действует как попытка / окончание, когда окончание удаляет использованный объект. Таким образом, он подходит только для объектов, которые реализуют IDisposable
,
Он выдает исключение, поэтому либо ваш содержащий метод должен обработать его, либо передать его в стек.
try
{
using (
StreamReader rdr = File.OpenText("file.txt"))
{ //do stuff
}
}
catch (FileNotFoundException Ex)
{
// The file didn't exist
}
catch (AccessViolationException Ex)
{
// You don't have the permission to open this
}
catch (Exception Ex)
{
// Something happened!
}
Любые исключения, которые генерируются в выражении инициализации оператора using, распространяются вверх по области метода и стеку вызовов, как и ожидалось.
Однако следует обратить внимание на то, что если в выражении инициализации возникает исключение, то метод Dispose() не будет вызываться для переменной выражения. Это почти всегда то поведение, которое вы хотели бы, так как вы не хотите беспокоиться об удалении объекта, который на самом деле не был создан. Однако может возникнуть проблема в сложных обстоятельствах. То есть, если в конструкторе скрыты несколько инициализаций, а некоторые завершены успешно до того, как было сгенерировано исключение, вызов Dispose в этот момент может не произойти. Однако обычно это не проблема, поскольку конструкторы обычно просты.
Использование не мешает обработке исключений, кроме очистки вещей в своей области.
Он не обрабатывает исключения, но пропускает исключения.
В вашем примере, если File.OpenText
броски Dispose
не будет называться.
Если исключение происходит в //do stuff
, Dispose
будет называться.
В обоих случаях исключение обычно распространяется вне области действия, как это было бы без оператора using.
using
гарантирует *, что созданный объект будет расположен в конце блока, даже если будет сгенерировано исключение. Исключение не поймано. Тем не менее, вы должны быть осторожны с тем, что вы делаете, если вы пытаетесь поймать это самостоятельно. Поскольку любой код, который перехватывает исключение, находится за пределами блока контекста, определенного using
утверждение, ваш объект не будет доступен для этого кода.
* за исключением обычных подозреваемых, таких как сбой питания, ядерный холокост и т. д.
Если вы специально не ловите исключение, оно выбрасывается в стек, пока что-то не сработает
Вы можете вообразить использование блока try...finally без блока catch. В блоке finally вызывается IDisposable.Dispose, и, поскольку нет блока catch, любые исключения выбрасываются в стек.
"использование" не перехватывает исключения, оно просто избавляется от ресурсов в случае необработанных исключений.
Возможно, вопрос заключается в том, будет ли он распоряжаться ресурсами, выделенными в скобках, если в объявлении также произошла ошибка? Трудно представить, как это происходит.