“使用”语句与大括号

时间:2013-08-14 09:25:35

标签: c# scope using curly-braces

我想知道为什么我们在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...
     }
}

两种方法之间是否存在显着差异?

6 个答案:

答案 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

撰写的这篇优秀文章