我想知道如果我执行using
或return
操作,throw
语句中创建的对象是否会被处理掉。示例如下。
using(SomeClass thing = new SomeClass())
{
...
if(condition)
return;
...
}
以上是否会混淆或者GC在这里受到信任?
答案 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
}
}
这将在 sqlConn
和 sqlCmd
的作用域完成时处理并关闭它们,但 在 using 作用域中声明的 reader
没有 Dispose()
自动调用它。