`using`是否处理了在其中声明的所有对象?

时间:2012-09-13 16:31:29

标签: c#

我想知道如果我执行usingreturn操作,throw语句中创建的对象是否会被处理掉。示例如下。

using(SomeClass thing = new SomeClass())
{
  ...
  if(condition)
    return;
  ...
}

以上是否会混淆或者GC在这里受到信任?

7 个答案:

答案 0 :(得分:7)

是的,它会的。 using语句将导致创建finally块。即使在相关finally块中抛出异常,或者该try块中存在try语句,也会运行return块的代码。

只有少数例外可能会导致finally块的代码无法执行,并且它们都列在here,但我的猜测是,在您的情况下,您将能够忍受这些后果。

答案 1 :(得分:2)

using相当于try-finally所以,是的,确实如此。

答案 2 :(得分:2)

如果实施则处置将始终被调用。它相当于在finally块中调用dispose。

答案 3 :(得分:2)

它会处置,是的。它将在CIL代码中创建一个finally块。

答案 4 :(得分:2)

是的,因为编译器最终会将using扩展为try。处置将发生在finally块内。此外,finally将包含一个测试,以检查using中的变量是否为null(如果构造函数中存在异常)。

答案 5 :(得分:2)

撰写使用声明时:

using(SomeClass thing = new SomeClass())
{
    //...
    if (condition)
        return;
    //...
}

这将产生以下代码:

SomeClass thing;
try
{
    thing = new SomeClass();
    //...
    if (condition)
        return;
    //...
}
finally
{
    if(thing != null)
    {
        thing.Dispose();
    }
}        

因此,声明using ( /* HERE */ )的所有对象将自动处理。在{}内声明的对象不会。 但是你当然可以使用语句嵌套(或堆栈):

using (var thing = new SomeClass())
    using (var another = new Another())
        using (var somethingElse = new Whatever())
        {
            //...
        }

这当然只是写作的语法糖

using (var thing = new SomeClass())
{
    using (var another = new Another())
    {
        using (var somethingElse = new Whatever())
        {
            //...
        }
    }
}

因为当一个语句后跟一个代码块(在这种情况下是另一个using - 块)时,你可以跳过花括号......

当使用两个或多个相同类型的对象时,您可以在using - 语句中链接声明:

using (MemoryStream stream = new MemoryStream(), stream2 = new MemoryStream())
{
    //...
}

(感谢@Gratzy指出这一点)

答案 6 :(得分:1)

对我来说,问题与细节不匹配,细节在这里已经解决了一堆但不是标题问题......

<块引用>

using 是否处置了其中声明的所有对象?

,它没有。它只为声明中的对象调用 Dispose()。它不会为在其中声明的对象调用 Dispose()

我经常在代码中看到这种东西

using(var sqlConn = new SqlConnection("connStr"))
using(var sqlCmd = new SqlCmd("CmdText", sqlConn))
{
   sqlConn.Open();
   var reader = sqlCmd.ExecuteReader();
   while (reader.Read())
   {
     //stuff is done
   }
}

这将在 sqlConnsqlCmd 的作用域完成时处理并关闭它们,但 在 using 作用域中声明的 reader 没有 Dispose() 自动调用它。