这可以在其他地方回答,但经过一些搜索后,我发现在正常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
对象是否会被处置掉?
哪种语法更受欢迎?我个人认为第二个更干净,但我知道可读性也可以在这里发挥作用。
答案 0 :(得分:10)
对于您的第二个代码,当流离开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
就是{{1}}。
答案 1 :(得分:4)
没有
using
语句仅适用于语句中直接声明的资源;而不是初始化程序中的其他分配。
每个资源都需要单独的using
语句。
答案 2 :(得分:2)
According to 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
这样做。但它没有,它不应该:它没有创建对象,因此它也不能破坏它。
答案 3 :(得分:2)
当然,已有答案可以正确解释这一点。这被其他人提到的规范所涵盖。
但你可以尝试一下。这是一个例子:
static class Program
{
static void Main()
{
using (new DisposeMe("outer", new DisposeMe("inner", null)))
{
Console.WriteLine("inside using");
}
Console.WriteLine("after using scope");
}
}
class DisposeMe : IDisposable
{
public readonly string name;
public DisposeMe(string name, object dummy)
{
this.name = name;
}
public void Dispose()
{
Console.WriteLine("'Dispose' was called on instance named " + name);
}
}
输出:
inside using 'Dispose' was called on instance named outer after using scope
(当然如果你嵌套两个using
语句,就像在using (var inner = new DisposeMe("inner", null))
{
using (new DisposeMe("outer", inner))
{ ... } }
中一样,在两个对象上调用Dispose
方法。)