2011-06-15 57 views
6

例如如果使用块返回,是否会处理IDisposable?

using(var something = GetSomething()) 
{ 
    something.DoSomething(); 
    if(something.IsX()) return true; 
} 
return false; 
+0

嗯,这是一个有趣的,你做一个GetSomething()而不是一个新的东西。我不认为这个框架有区分差异的智能。如果Something是一个单例,那么退出后可能会得到“DisposedObject”异常。您可以构建一个小型测试应用程序,以了解框架在Using(GetSomething())中的作用。 – 2011-06-15 11:00:00

回答

8

是的,绝对。 Dispose方法被调用,但是using语句被执行,除非它是一个突然的全进程终止。最常见的情况是:

  • return
  • 例外被块
  • 到达块自然

的端部基本上是一个内抛出(和未被捕获)的块内using声明主要是一个try/finally区块的语法糖 - 而finally具有所有相同的属性。

编辑:从C# 4 specification的第8.13节:

一个using语句stranslated分为三个部分:获取,使用和处置。资源的使用隐含在包含finally子句的try语句中。此finally子句配置资源。

finally语句在说明书的部分说明8.10:在控制离开try语句

一个finally块的语句总是执行。无论控制转移是否由于正常执行而发生,都是如此;作为执行break,continuegotoreturn声明的结果;或者由于传播了try声明中的例外。

+1

我知道你是Jon Skeet,但你能引用一个参考吗? :) – 2011-06-15 10:31:14

+5

@Louis:不可能 - 所有文档参考Jon Skeet。 – mdm 2011-06-15 10:33:49

+0

我添加了文档和代码示例的链接。 – 2011-06-15 10:36:20

0

据我所知,使用块只要退出范围就会处理该对象。

例如,当返回true时,下一个语句超出范围,因此变量将被丢弃。

0

我只要控制会走出{}处置想到会被调用,所以在短期Yes

1

是的,用的就是一个编译器功能,其扩展到

try { 
    ... 
    return ...; 
} 
finally { 
    foo.Dispose(); 
} 
2

是。

using is syntactic sugar for a try/finally block

using语句确保 处置是即使当你调用对象的方法 发生异常 调用。通过将对象 置于try块内,然后调用 在finally块中处理,可以实现 的相同结果;

In the documentation on the finally block

而捕获用于处理发生在一份声明中 块 例外,最终被用于保证无论在前的是如何尝试 代码 语句块执行 块已退出。

因此,using被转换为try/finally,随着finally部分.Dispose(),确保其始终执行,无论在try/catch语句会发生什么。

0

尚未提及的一点是,尽管“使用”块中的“返回”将调用控制变量上的Dispose,但迭代器中“使用”块内的“yield return”不会处理受控除非与迭代器关联的IEnumerator被Disposed。

相关问题