1

我想知道如果我执行or操作,using语句中创建的对象是否会被释放。示例如下。returnthrow

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

上面会混淆还是GC在这里值得信任?

4

7 回答 7

7

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

只有少数例外情况会导致finally块的代码不被执行,它们都列在这里,但我的猜测是,在你的情况下,你将能够承受这些后果。

于 2012-09-13T16:32:54.437 回答
2

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

于 2012-09-13T16:34:03.393 回答
2

using是等价的try-finally,是的,确实如此。

于 2012-09-13T16:33:32.613 回答
2

如果实现了 dispose ,它将始终被调用。它相当于在 finally 块中调用 dispose。

于 2012-09-13T16:33:34.300 回答
2

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

于 2012-09-13T16:33:49.527 回答
2

编写 using 语句时:

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 */ )都会自动处理。在{}will not 中声明的对象。但是您当然可以使用语句嵌套(或堆栈):

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-block)时,你可以跳过花括号......

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

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

(感谢@Gratzy 指出这一点)

于 2012-09-13T16:41:39.297 回答
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当范围完成时,那些在使用范围中声明的reader并没有自动调用它。Dispose()

于 2021-07-16T03:46:19.043 回答