如果我在使用声明结束之前返回,会发生什么情况? 这个configuration会被调用吗?
我有下面的代码
using(MemoryStream ms = new MemoryStream()) { //code return 0; }
dispose()
方法在using
语句大括号}
右边被调用? 由于我在using
语句结束之前return
, MemoryStream
对象是否会正确处理? 这里发生了什么?
是的,将会调用Dispose
。 只要执行离开using
块的范围,就会立即调用它,而不pipe离开块的方式,块的执行结束, return
语句还是exception。
正如@Noldorin正确地指出的那样,在代码中使用一个using
块被编译成try
/ finally
,而在finally
块中调用Dispose
。 例如下面的代码:
using(MemoryStream ms = new MemoryStream()) { //code return 0; }
有效地变成:
MemoryStream ms = new MemoryStream(); try { // code return 0; } finally { ms.Dispose(); }
因此,不pipe执行path如何, try
块保证执行完毕后都会执行,无论如何保证了Dispose
被调用。
有关更多信息,请参阅此MSDN文章 。
附录:
只需要添加一点警告:因为Dispose
保证被调用,所以确保Dispose
在实现IDisposable
时不会抛出exception几乎总是一个好主意。 不幸的是,核心库中有一些类在Dispose
被调用的时候会抛出某些情况 – 我在看你,WCF服务引用/客户端代理! – 当发生这种情况时,如果在exception堆栈展开过程中调用Dispose
,则可能很难find原来的exception,因为原来的exception被吞噬,以支持由Dispose
调用产生的新exception。 这可能令人生气,令人沮丧。 还是令人沮丧的疯狂? 其中之一。 也许两个。
using
语句的行为与try ... finally
块完全相同,因此将始终在任何代码出口path上执行。 但是,我相信他们是受到less数和罕见的情况下, finally
块不被称为。 我记得的一个例子是,如果前台线程退出而后台线程处于活动状态:GC之外的所有线程都暂停,这意味着finally
块不会运行。
明显的编辑:它们的行为与让他们处理IDisposable对象的逻辑相同。
奖励内容:可以堆叠(types不同):
using (SqlConnection conn = new SqlConnection("string")) using (SqlCommand comm = new SqlCommand("", conn)) { }
还有逗号分隔(types相同):
using (SqlCommand comm = new SqlCommand("", conn), SqlCommand comm2 = new SqlCommand("", conn)) { }
你的MemoryStream对象将被正确处理,不需要担心。
使用using
语句,无论完成path如何,该对象都将被丢弃。
进一步阅读…
编译后在reflection器中查看你的代码。 你会发现编译器重构代码以确保在stream上调用dispose。