使用(.....){...} 的意思是什么?

6
可能有重复:
在C#中使用using语句
什么是C# Using块,为什么要使用它?

只是想知道这是什么意思?我在很多在线教程中看到了这种语法:

using (SqlCeCommand cmd2 = new SqlCeCommand("SELECT city FROM cities JOIN states ON states.id=cities.state WHERE states.state='" + read.GetString(0) + "'", con))
{
  SqlCeDataReader readCities = cmd2.ExecuteReader();
  while (readCities.Read())
  {
    parent.Nodes.Add(readCities.GetString(0));
  }
}

为什么要使用它?我尝试在谷歌上搜索,但只出现了用于包含 dll 和其他文件的 'using' 关键字。


11
请参阅C#规范的第8.13节。 - Eric Lippert
2
请参考此答案:https://dev59.com/bkbRa4cB1Zd3GeqP3scO - AdamW
2
你也可以在这里快速搜索一下,你会发现你已经创建了一个重复的问题。 - John Saunders
1
Zano:这可能对他在这里没有什么帮助,这取决于他是否知道他正在寻找什么。在C#中,“using”关键字有两个完全不同的含义。 - Ken
1
我怀疑大多数开发人员甚至没有意识到C#规范的存在。 - Greg
显示剩余3条评论
8个回答

33

using语句

using(var disposableObject = new object_that_implements_IDisposable()) { ... }

"

"是语法糖,用于类似以下代码的内容:

var disposableObject = new object_that_implements_IDisposable()
try
{
    ...
}
finally
{
    if(disposableObject != null)
    {
        ((IDisposable)your_object).Dispose();
    }
}

这仅适用于实现了IDisposable接口的类。它有助于清理代码,其中您拥有需要在完成后清理的对象,例如系统资源(文件句柄、数据库连接、套接字等)。理论上,您可以省略.Dispose()调用,但是然后您必须等待垃圾回收器释放保留的资源。 GC非常擅长知道何时释放对象以回收其内存使用情况,但是它不知道它需要释放对象以让它们放弃其他系统资源。因此,在所有者决定需要内存使用的资源之后,这些关键资源可能不会被释放。因此,当您完成时一定要处理您的对象(如果它们是可处理的)!
至于为什么要使用using而不是try / finally,那纯粹是程序员的喜好。我更喜欢using,因为您可以级联它们:
using(var a = new class())
using(var b = new class())
using(var c = new class())
using(var d = new class())
{
    ...
}

如果使用try/finally语句,需要编写更多的代码才能实现相同的功能。

using语句还具有其他优点。例如,如果x为空,直接调用x.Dispose可能会抛出NullReferenceException异常,但是使用using(x)不会。

另请参阅:


关键是“您必须等待垃圾收集器释放保留的资源。” +1 - Eugene Yokota
2
当离开一个 using 块时,将调用 IDisposable.Dispose。如果您还明确定义了 IDisposable.Dispose,则这可能与对象定义的 Dispose 方法不同。 - Kevin Kibler
感谢您编辑并修正了变量声明和初始化在 try 前的位置。我已删除指出错误的评论。 - GBegen
+1 我不知道级联语法技巧。 - Stefano Ricciardi

4
using只是指示编译器编写代码以调用您正在使用的变量上的Dispose方法。只有实现了“IDisposable”接口的类型才能与using语句一起使用。
在您的示例中,当{}中的代码完成时,cmd2将被处理。

好的,我理解了,但为什么要用那样的措辞?在我看来,“using”并没有传达“嘿编译器,请帮我清理一下”的意思。 - FoxDeploy

2

“定义一个范围,在该范围之外,一个或多个对象将被处理”
参见using语句


2

using适用于实现IDisposable接口的对象。它确保在离开using块时(无论是正常离开还是通过异常或其他方式),可释放对象的Dispose方法都会被调用。


0

使用using语句定义了一个作用域,在该作用域之外,对象或对象将被处理。


0

始终实现 IDisposable 的一个。 - John Saunders

0

查看http://msdn.microsoft.com/en-us/library/yh598w02(VS.80).aspx

using语句将变量封装在其作用域内。当执行退出using块时,其中的所有对象都从内存中释放。您可能会在DB连接中看到它,以便当using块退出时,分配给该连接的资源被清理和关闭。


-1

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