C#: 使用“using”初始化变量

5
关于以下代码:
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
  code...
}

SqlConnection是否使用“using”进行初始化,以便在括号后取消引用/销毁?

如有必要,请纠正我的问题。

5个回答

8

using是在调用对象的Dispose()方法时的语法快捷方式。

当括号中的代码执行完毕后,using语句中包装的对象的Dispose()方法会自动被调用。

编译时,上述代码实际上会被扩展为:

{
  SqlConnection sqlConnection = new SqlConnection(connectionString);
  try
  {
    // .. code
  }
  finally
  {
    if (sqlConnection!= null)
      ((IDisposable)sqlConnection).Dispose();
  }
}

你可以看到这是一个方便的快捷方式。

如果我想要给这个代码块添加一个catch子句,你会推荐把"using"快捷方式转换为try-catch-finally,还是将using包装在一个try catch中?我认为后者存在问题,但确切原因我不确定。 - Nick Vaccaro
1
只需将try..catch包装在using块周围:try { using(var db = new SqlConnection(connectionString)) { code ... } catch { panic... } 或者将其放在其中:using(var db = new SqlConnection(connectionString)) { try { code... } catch { panic...} } - 这取决于您是否想捕获由"new SqlConnection(connectionString)"引发的异常。 - Michael Stum
3
我会把使用放在try-catch语句中。 - TheSean
谢谢大家。我已经这样做了。 - Nick Vaccaro

6
是的。 using语句只是一种语法糖,编译器会将其转换成类似以下的内容。
SqlConnection sqlConnection;
try
{
  sqlConnection = new SqlConnection(connectionString);
  // code...
}
finally
{
  if (sqlConnection != null)
     sqlConnection.Dispose();
}

6
它还将名称“sqlConnection”限定在该代码块中,因此如果您在其被释放后尝试使用它,则会收到编译器错误。 - ctford
如果是这样编译的,你能用'Using'块捕获异常吗? - contactmatt
1
请注意,在此处finallysqlConnection尚未被明确赋值... - Marc Gravell

2

using是一种语言结构,它接受一个IDisposable对象并调用其Dispose()方法。

因此,

using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
  code...
}

大致相当于

SqlConnection sqlConnection = null;
try {
    sqlConnection = new SqlConnection(connectionString));
    code ...
} finally {
    if(sqlConnection != null) sqlConnection.Dispose();
}

2
能否换个新词来描述语法糖?每次都用这个词真的有点腻了。 - Dan
3
“Syntactic sugar”是一个术语,指的是新语法,仅仅是对语言中已经表达的概念进行了简洁的表述。它不会消失。 - Dan Davies Brackett
1
语法糖通常用于贬低某些概念,认为这只是“针对不懂语言的业余爱好者”的东西。在C#中也可以看到自动属性(问题9304)。但我认为“使用”并不是贬义的,它是一种非常棒的语法糖,就像foreach语句对“GetEnumerator”调用的封装一样。因此,我更喜欢使用术语“语言结构”,因为这使它看起来像一个一等公民,而在我看来,它确实是如此。 - Michael Stum
迈克尔,这是一个支持保留“语法糖”以保持其积极含义的好论点。 - Steven Sudit

0
sqlConnection变量超出范围(在括号块的末尾)时,Dispose()方法将自动调用。

0

使用完毕后,它将退出其可用范围。对象的Dispose方法将被调用,但该对象不一定会在此时被垃圾回收。

这意味着,如果您有在对象的Dispose()方法中清理(关闭文件等)的项目,它们将在using语句结束后立即清理。如果您还有一个终结器(~YourClassName),它会做其他事情,那么不能保证它会在那个时候被调用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接