这可能在其他地方得到回答,但在进行了一些搜索之后,我在正常的using
上下文之外并没有找到太多关于这个主题的内容。
我很好奇是否所有在using
块中创建的对象都会和原始对象一样被释放。
这里是上下文:
通常我会做这样的事情:
using (var conn = new SqlConnection(connectionString))
using (var cmd = new SqlCommand(commandText, conn))
{
//Do everything I need to here
}
我知道conn
和cmd
在这一点上都超出了范围,并且因为可爱的using
关键字而被释放。
我很好奇,同样的处置规则是否适用于以下声明:
using (var cmd = new (SqlCommand(commandText, new SqlConnection(ConnectionString)))
{
//Do everything I need here
}
当SqlConnection
超出作用域并由于与对象关联而被释放时,using
语句中内联创建的cmd
对象会被释放吗?
另外,哪一种在语法上是首选的?我个人认为第二个更干净,但我知道可读性也可能在这里发挥。
发布于 2014-02-18 12:34:26
对于第二段代码,当流离开Dispose
块时,不会在SqlConnection
实例上调用using
,除非SqlCommand.Dispose()
在内部这样做(不,它没有)。
根据规范(8.13),将using (ResourceType resource = expression) statement
转换为:
{
ResourceType resource = expression;
try {
statement;
}
finally {
if(resource != null)
((IDisposable)resource).Dispose();
}
}
在您的代码中,resource
是SqlCommand
,这是调用Dispose
的一个。
发布于 2014-02-18 12:35:10
不是的。
using
语句只应用于语句中直接声明的资源,而不应用于初始化程序中的其他分配。
对于每个资源,您需要一个单独的using
语句。
发布于 2014-02-18 12:41:15
根据MSDN,此代码:
using (var temp = obj)
{
// ...
}
翻译为(包括额外的花括号以限制范围):
{
var temp = obj;
try
{
// ...
}
finally
{
if (temp != null)
((IDisposable)temp).Dispose();
}
}
如您所见,如果您将obj
替换为new SqlCommand(commandText, new SqlConnection(ConnectionString))
,那么只有SqlCommand
才会得到正确的处理。
{
SqlCommand temp = new SqlCommand(commandText,
new SqlConnection(ConnectionString));
try
{
// ...
}
finally
{
if (temp != null)
((IDisposable)temp).Dispose();
}
}
因此,除非已释放的SqlConnection
这样做,否则SqlCommand
不会被释放。但是它没有,也不应该:它没有创建对象,因此它也不能破坏它。
https://stackoverflow.com/questions/21864676
复制相似问题