我想知道为什么我们在C#中使用using
语句。我查了一下,发现它用于执行语句然后清理对象。所以我的问题是:如果我们打开并关闭大括号({ }
)来定义范围,那不是一回事吗?
使用声明:
using (SqlConnection conn = new SqlConnection(connString)) {
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT * FROM Customers";
conn.Open();
using (SqlDataReader dr = cmd.ExecuteReader()) {
while (dr.Read())
// Do Something...
}
}
Curly Brackets:
{
SqlConnection conn = new SqlConnection(connString);
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "SELECT * FROM Customers";
conn.Open();
{
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
// Do Something...
}
}
两种方法之间是否存在显着差异?
答案 0 :(得分:5)
好吧,使用(当且仅当该类实现IDisposable
接口时才合法)
using (SqlConnection conn = new SqlConnection(connString)) {
// Some Code
...
}
等于这段代码
SqlConnection conn = null;
try {
SqlConnection conn = new SqlConnection(connString);
// Some Code
...
}
finally {
if (!Object.ReferenceEquals(null, conn))
conn.Dispose();
}
C#与C ++没有相同的行为,所以不像在C ++中那样在C#中使用 {...}模式:
{
SqlConnection conn = new SqlConnection(connString);
...
// Here at {...} block exit system's behavior is quite different:
//
// C++: conn destructor will be called,
// resources (db connection) will be safely freed
//
// C#: nothing will have happened!
// Sometimes later on (if only!) GC (garbage collector)
// will collect conn istance and free resources (db connection).
// So, in case of C#, we have a resource leak
}
答案 1 :(得分:3)
花括号只显示块的代码
使用指示GC处理。
任何实现IDisposable的类都可以与Using使用。
使用将基本上转化为(注意没有捕获)。如果有任何异常,它将被抛弃。但即便如此,连接也会处理
SqlConnection conn;
try
{
conn = new SqlConnection(connString);
}
finally
{
if (conn != null)
conn.Dispose();
}
答案 2 :(得分:1)
命名空间更改名称查找,而花括号创建一个新堆栈,可在其中创建局部变量。
答案 3 :(得分:1)
如果您使用带有 键 的版本,则.NET平台会运行方法 Dispose 以释放对象使用的资源。因此该对象必须实现 IDisposable 接口。通过这种方式,您可以以确定的方式释放资源(与垃圾收集器不同)。
强烈建议在方法 Dispose 中清除 NOT托管资源,因为 GC 不会清除它。
Curly括号仅确定其中使用的变量的范围,但在运行时到达close括号后不会清除资源。 GC 根据其算法以非确定性方式进行。
答案 4 :(得分:1)
使用时
using( ...){
... code
}
这实际上是使用模式,c#编译器发出代码来调用使用块中创建的对象实现的dispose方法。
因此,对于任何实现IDisposable接口的对象,您都可以使用
using(var disposableObject = new DisposableObject()){
}
当编译compliler时会生成代码
DisposableObject disposableObject = null;
try
{
disposableObject = new DisposableObject();
}
finally{
disposableObject.Dispose();
}
因此,使用(..)语句确保即使在using语句中抛出任何异常,也会调用一次性对象的dispose方法。
答案 5 :(得分:0)
使用等同于以下
SqlConnection conn;
try
{
conn = new SqlConnection(connString)
}
finally
{
conn.Dispose() //using does this automatically for you
}
规则是当某个类实现
IDisposable
时,您可以使用USing 阻止而不是尝试catch,最后是模式
如果您想更深入地了解GC的工作原理,请阅读Jeffery Richter
撰写的这篇优秀文章