C#“使用”语法
使用捕获exception还是抛出它? 即
using (StreamReader rdr = File.OpenText("file.txt")) { //do stuff }
如果streamreader抛出一个exception是通过使用或抛出来捕获,所以调用函数可以处理它?
使用语句不要吃例外。
所有的“使用”都是把你的对象作用于使用块,并在对象离开块时自动调用Dispose()。
尽pipe如此,如果一个线程被外部源强制中止,可能Dispose永远不会被调用。
当您看到使用语句时,请考虑以下代码:
StreadReader rdr = null; try { rdr = File.OpenText("file.txt"); //do stuff } finally { if (rdr != null) rdr.Dispose(); }
所以真正的答案是它不会对使用块体中抛出的exception做任何事情。 它不处理或重新抛出它。
using
允许exception煮沸。 它像try / finally一样,最终放置使用的对象。 因此,对于实现IDisposable
对象来说只是适用的/有用的。
它抛出exception,所以你的包含方法需要处理它,或者把它传递给堆栈。
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语句的初始化expression式中引发的任何exception将按预期方式传播方法作用域和调用堆栈。
但是要注意的一点是,如果在初始化expression式中发生exception,则不会在expression式variables上调用Dispose()方法。 这几乎总是您想要的行为,因为您不想打扰处理实际上未创build的对象。 但是,在复杂的情况下可能会出现问题。 也就是说,如果多个初始化被隐藏在构造函数中,并且有一些在抛出exception之前成功,那么Dispose调用可能不会在这个时候发生。 这通常不是问题,因为构造函数通常很简单。
如果你没有特别的捕捉exception,它会抛出堆栈,直到出现exception
除了在范围内清理东西之外,使用不会影响exception处理。
它不处理exception,但让exception通过。
using
保证*即使发生exception,创build的对象也将被放置在块的末尾。 exception没有被捕获。 但是,如果你想自己去捕捉,你需要小心你所做的事情。 由于任何捕获exception的代码都在using
语句定义的范围块之外,因此您的对象将不可用于该代码。
*禁止像电源故障,核浩劫等常见的嫌疑人
在你的例子中,如果File.OpenText
抛出, Dispose
将不会被调用。
如果发生exception, 则会调用Dispose
。
在这两种情况下,exception通常都在范围之外传播,因为它没有使用声明。
你可以想象用 try … finally块没有catch块。 在finally块中,IDisposable.Dispose被调用,并且由于没有catch块,任何exception都被抛出堆栈。
它被抛出。
“使用”不会捕获exception,只是在未处理exception的情况下处理资源。
也许问题是,如果在声明中发生错误,是否会处理在括号中分配的资源? 不过,很难想象这两者都发生了。