"using"结构的基础知识

6

如果我使用 "using" 结构,我知道对象会自动被处理。但是如果 "using" 结构中的语句引发异常,那么会发生什么? "using" 对象是否仍然被处理?如果是,那么是在什么时候处理的?

3个回答

11

using块在编译器中被转换为以下代码:

DisposableType yourObj = new DisposableType();
try
{
    //contents of using block
}
finally
{
    ((IDisposable)yourObj).Dispose();
}

Dispose()调用放在finally块中可以确保Dispose始终被调用 - 当然,除非异常发生在实例化站点之外(因为那是在try之外发生的)。

重要的是要记住,using不是一种特殊的运算符或结构 - 它只是编译器用稍微更晦涩的其他东西替换的东西。


还需要注意的是,正如您的示例所说明的那样,如果对 DisposableType() 的调用引发异常,则 Dispose() 将不会被调用;在异常之前分配的任何资源都不会被释放。 - Ben
finally 块中也有一个 null 测试。 - Ani
+1 这完全就是手册上所说的。http://msdn.microsoft.com/zh-cn/library/yh598w02.aspx - MarkJ

2
实际上,使用块(block)等同于尝试-最终块(try-finally block),这确保了最终会始终执行,例如:
using (SqlConnection con = new SqlConnection(ConnectionString))
{
    using (SqlCommand cmd = new SqlCommand("Command", con))
    {
        con.Open();
        cmd.ExecuteNonQuery();
    }
}

等于

SqlConnection con =  null;
SqlCommand cmd = null;

try
{
    con = new SqlConnection(ConnectionString);
    cmd = new SqlCommand("Command", con);
    con.Open();
    cmd.ExecuteNonQuery();
}
finally
{
    if (null != cmd);
        cmd.Dispose();
    if (null != con)
        con.Dispose();
}

2

这篇文章讲得很清楚。

在内部,这个好东西会为分配的对象生成一个try / finally块,并为您调用Dispose()。 它省去了手动创建try / finally块和调用Dispose()的麻烦。


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