C# 通过 .NET Framework 公共语言运行库 (CLR) 来自动释放用来存储不再需要的对象的内存。内存的释放具有不确定性;一旦 CLR 决定执行垃圾回收,就会释放内存。但是,通常最好尽快释放诸如文件句柄和网络连接这样的有限资源。
传统的作法可能是:
FileStream fStream = null; try { fStream = new FileStream("c;//test.txt", FileMode.Create, FileAccess.ReadWrite); } finally { if (fStream != null) fStream.Close(); }
而C#提供了一种更简洁的安全释放资源的语句using,using语句有三种使用方式:
1、在using语句之中声明对象
using (ResourceType resource = expression) statement
using (Font font1 = new Font("Arial", 10.0f)) { //use font1 }
2、在using语句之前声明对象
using (expression) statement
Font font2 = new Font("Arial", 10.0f); using (font2) { // use font2 }
3、在using语句中声明多个同类型对象
using (ResourceType r1 = e1, r2 = e2, ..., rN = eN) statement
using (Font font3 = new Font("Arial", 10.0f), font4 = new Font("Arial", 10.0f)) { // Use font3 and font4. }
为 using 语句提供的对象必须实现 IDisposable 接口。此接口提供了 Dispose 方法,该方法将释放此对象的资源。
下面的示例显示用户定义类可以如何实现它自己的 Dispose 行为
using System; class C : IDisposable { public void UseLimitedResource() { Console.WriteLine("Using limited resource..."); } void IDisposable.Dispose() { Console.WriteLine("Disposing limited resource."); } } class Program { static void Main() { using (C c = new C()) { c.UseLimitedResource(); } Console.WriteLine("Now outside using statement."); Console.ReadLine(); } }
using 语句被翻译成三个部分:获取、使用和处置。资源的使用部分被隐式封闭在一个含有 finally 子句的 try 语句中。此 finally 子句用于处置资源。如果所获取资源是 null,则不会对 Dispose 进行调用,也不会引发任何异常。
下列形式的 using 语句
using (ResourceType resource = expression) statement
对应于下列两个可能的扩展中的一个。当 ResourceType 是值类型时,扩展为
{ ResourceType resource = expression; try { //statement; } finally { ((IDisposable)resource).Dispose(); } }
否则,当 ResourceType 是引用类型时,扩展为
{ ResourceType resource = expression; try { //statement; } finally { if (resource != null) ((IDisposable)resource).Dispose(); } }
下列形式的 using 语句
using (expression) statement
同样具有上述两种可能的扩展,但在这种情况下 ResourceType 隐式地为 expression 的编译时类型,而 resource 变量在嵌入语句中既不可访问,也不可见。
如果资源获取采用局部变量声明的形式,则有可能获取给定类型的多个资源。下列形式的 using 语句
using (ResourceType r1 = e1, r2 = e2, ..., rN = eN) statement
完全等效于嵌套 using 语句的序列:
using (ResourceType r1 = e1) using (ResourceType r2 = e2) ... using (ResourceType rN = eN) statement
在形式1和3的using语句中,resource 变量在嵌入语句中都是只读的,对它们的赋值语句会导致编译器的错误提示:
“xxx”是一个“using 变量”,无法为它赋值”
同时变量的作用域仅在嵌入语句内部
形式2,的情况比较特别,嵌入语句中可以对using所引用的变量赋值,但会得到一个编译器警告,同时对变量的赋值将引起Dispose的调用,但仅一次:
C c = new C(); using (c) { c = new C(); c = null; }
参考资料:
using 语句(C# 参考)
http://msdn.microsoft.com/zh-cn/library/yh598w02(VS.80).aspx
C#语言规范 8.13