当在'using'块内调用'return'时会发生什么?

18

如果我有一个像这样的using块的方法...

    public IEnumerable<Person> GetPersons()
    {
        using (var context = new linqAssignmentsDataContext())
        {
            return context.Persons.Where(p => p.LastName.Contans("dahl"));
        }
    }

如果在 using 块内部返回值,IDisposable 对象是否仍会被处理?


参见https://dev59.com/NHRB5IYBdhLWcg3wUFvB和https://dev59.com/DkjSa4cB1Zd3GeqPHrr_ - Jørn Schou-Rode
1
使用ILDASM或Reflector查看您生成的代码。 - No Refunds No Returns
2个回答

29

是的,它确实会释放对象。该对象的处理发生在finally块中,即使遇到return调用也会执行。它本质上扩展为以下代码:

var context = new linqAssignmentsDataContext();
try {
  return context.Persons.Where(p => p.LastName.Contans("dahl"));
} finally {
  if ( context != null ) {
    context.Dispose();
  }
}

7
MSDN文档中得知:
使用using语句可以确保在调用对象方法时发生异常时也会调用Dispose方法。您可以通过将对象放置在try块中,然后在finally块中调用Dispose来实现相同的结果。事实上,这就是编译器如何将using语句转换的方式。
因此,无论如何都会处理该对象,除非您拔掉电源线。

13
因此,该物体总是被处理掉。除非您拔出电源电缆之外。在这种情况下,随着电子散开,对象被处理掉;-) - Nick
1
让我想起了这篇TheDailyWTF文章(第一篇):http://thedailywtf.com/Articles/My-Tales.aspx - Tamas Czinege
1
调用 Environment.FailFast 方法不仅会断电,还不会调用 Dispose 方法。 - Robert Davis
1
Robert Davis:在.NET中,堆栈溢出也会关闭进程,而不执行finally块。 - Tamas Czinege
是的,那只是一个例子。当我写下那个答案的时候,我也想到了TheDailyWTF的文章... ;) - AndiDog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接