我看到在大多数示例中,SqlCommand
都是这样使用的
using (SqlConnection con = new SqlConnection(CNN_STRING))
{
using (SqlCommand cmd = new SqlCommand("Select ID,Name From Person", con))
{
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
return ds;
}
}
我知道我们为什么要使用using
语句,但是SqlCommand
不包含Close()
方法,所以我们真的应该在using
语句中使用它吗?
4条答案
按热度按时间iq0todco1#
因为它也实现了
IDisposable
。Using语句的目的是,当控件到达使用结束时,它将处理使用块的对象并释放内存。它的目的不仅是自动关闭连接,基本上它将处理连接对象,显然连接也会因此而关闭。
它的目的是释放Using语句中使用的资源。
根据MSDN:
通常,当你使用
IDisposable
对象时,你应该在using语句中声明和示例化它。using语句以正确的方式调用对象上的Dispose
方法,并且(当您像前面所示的那样使用它时)它还会导致对象本身在Dispose
被调用时脱离作用域。该对象是只读的,无法修改或重新分配。using语句确保即使在调用对象的方法时发生异常,
Dispose
也会被调用。通过将对象放入try块中,然后在finally
块中调用Dispose
,可以获得相同的结果;实际上,编译器就是这样翻译using语句的。2前面的代码示例在编译时扩展为下面的代码(注意额外的花括号,为对象创建了有限的作用域):注:
您可以示例化资源对象,然后将变量传递给using语句,但这不是最佳做法。在这种情况下,在控制离开using块后,对象仍保留在作用域中,即使它可能不再具有对其非托管资源的访问权限。换句话说,它将不再被完全初始化。如果您尝试在using块之外使用对象,您可能会引发异常。因此,通常最好在using语句中示例化对象,并将其作用域限制在using块中。
pprl5pva2#
SqlCommand
确实实现了IDisposable
,using
语句将在using块完成之前调用.Dispose()
。我不确定SqlCommand.Dispose()
的作用,但在您完成的示例上调用.Dispose()
是个好主意,即它可能会清除数据库连接。k10s72fa3#
SqlCommand.Dispose()用于释放SqlCommand所使用的所有资源。
3pmvbmvn4#
我做了一些研究,找到了一个答案,我总结如下。
SqlCommand
的using
陈述式不会处置整个批次。SqlCommand
间接继承自实作完成项的Component
。除非实作已经变更,否则GC在第一次遇到范围外的完成项时,会忽略具有完成项的对象。GC不是从内存中移除它,而是呼叫完成项,然后继续进行。第二次遇到完成项时,GC将从内存中删除该对象。2这显然是相当昂贵的,所以你不希望终结器经常运行。为了防止终结器运行,
Component
(SqlCommand
间接继承自它)实现了一个dispose方法,该方法告诉GC不要调用终结器,因为dispose方法已经处理了任何清除。简而言之,围绕
SqlCommand
的using
语句没有做任何特殊的事情,但是它阻止了更昂贵的终结器被调用。如果你有更多的细节到这是如何工作的,请让我知道在评论。