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的情况下处理资源。

也许问题是,如果在声明中发生错误,是否会处理在括号中分配的资源? 不过,很难想象这两者都发生了。