根据 MSDN 如果 IDisposable 资源
嵌套的内部using语句包含外部using的资源
语句中,嵌套资源的 Dispose 方法释放
包含的资源。
MSDN (http://msdn.microsoft.com/en-us/library/ms182334.aspx http://msdn.microsoft.com/en-us/library/ms182334.aspx) =>
示例 嵌套 using 语句(在 Visual Basic 中使用)可能会导致
违反 CA2202 警告。如果 IDisposable 资源
嵌套的内部using语句包含外部using的资源
语句中,嵌套资源的 Dispose 方法释放
包含的资源。当这种情况发生时,Dispose方法
外部 using 语句尝试将其资源处置为
第二次。在以下示例中,创建了一个 Stream 对象
外部 using 语句中的内容在内部 using 结束时被释放
StreamWriter 对象的 Dispose 方法中的语句
包含流对象。在外部 using 语句的末尾,
流对象被第二次释放。第二个版本是
违反 CA2202。
但是,如果我尝试这段代码,代码仍然有效并返回插入表中的计数。这与MSDN的解释相矛盾。我希望代码在 cmd.ExecuteScalar() 调用时崩溃,因为 conn 变量是在第一个内部 using 语句之后释放的。
为什么这仍然有效,为什么 conn 变量在第一次内部使用后没有被释放?
static void Main(string[] args)
{
var numbers= DoItGetIt();
}
private static int DoItGetIt()
{
using (var conn = new SqlConnection("Data Source=BestmixSql;Initial Catalog=Test;Integrated Security=True"))
{
conn.Open();
using (var cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = "INSERT INTO [Test].[dbo].[Tabel] VALUES (666)";
cmd.ExecuteNonQuery();
}
using (var cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = "SELECT COUNT(*) FROM [Test].[dbo].[Tabel]";
var count = cmd.ExecuteScalar();
return Convert.ToInt32(count);
}
}
}
您正在讨论的 MSDN 示例专门讨论了内部对象的场景占有外部物体;例如,一个StreamWriter
可以承担责任Stream
. In 那个场景,处理内部对象也会导致外部对象被处理 - 但在一般情况下情况并非如此。
特别是,命令不承担处置连接的责任。有趣的是,数据读取器can承担责任,但只能通过可选标志。
许多这样的对象提供标志来让调用者确定内部对象是否应该承担处理外部对象的责任。例如,StreamWriter
现在还提供了一个构造函数重载bool leaveOpen
范围。如果您将其传递为true
, the StreamWriter
does not级联Dispose()
.
This is all内部对象的实现细节,当它是专门为此编写的。这不是默认行为using
图案。
旁注:我想说 MSDN 在这里完全是错误的。这correct实现是第一个示例,有两个using
。第二个例子不直观,并且容易出现错误的实现。不要使用它。如果需要,请使用leaveOpen
to make 是明确的,但坦率地说,如果您无论如何都要处理它,那么没有它通常可以正常工作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)