标题：using
简介
定义一个范围，将在此范围之外释放一个或多个对象。
语法
using (Font font1 = new Font("Arial", 10.0f))
{
}
C# 语言参考
主要用途using 关键字有两个主要用途：(一).作为语句     用于定义一个范围，在此范围的末尾将释放对象
C# 通过 .NET Framework 公共语言运行库 (CLR) 自动释放用于存储不再需要的对象的内存。内存的释放具有不确定性；一旦 CLR 决定  执行垃圾回收，就会释放内存。但是，通常最好尽快释放诸如文件句柄和网络连接这样的有限资源。 
using 语句允许程序员指定使用资源的对象应当何时释放资源。为 using 语句提供的对象必须实现 IDisposable 接口。此接口提供了 Dispose 方法，该方法将释放此对象的资源。
可以在到达 using 语句的末尾时，或者在该语句结束之前引发了异常并且控制权离开语句块时，退出 using 语句。
1. 可以在 using 语句中声明对象（如上所示），或者在 using 语句之前声明对象，如下所示：
Font font2 = new Font("Arial", 10.0f);
using (font2)
{
// use font2
}
2. 可以有多个对象与 using 语句一起使用，但是必须在 using 语句内部声明这些对象，如下所示：
using (Font font3 = new Font("Arial", 10.0f), font4 = new Font("Arial", 10.0f))
{
// Use font3 and font4.
}示例1下面的示例显示用户定义类可以如何实现它自己的 Dispose 行为。注意类型必须从 IDisposable 继承。
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 System.Text;
②.为命名空间或类型创建别名。 
using Project = PC.MyCompany.Project;
using 指令的范围限制为包含它的文件。 
创建 using 别名，以便更易于将标识符限定到命名空间或类型。
创建 using 指令，以便在命名空间中使用类型而不必指定命名空间。using 指令不为您提供对嵌套在指定命名空间中的任何命名空间的访问。
命名空间分为两类：用户定义的命名空间和系统定义的命名空间。用户定义的命名空间是在代码中定义的命名空间。若要查看系统定义的命名空间的列表示例21.下面的示例显示了如何为命名空间定义和使用 using 别名：
namespace PC
{
// Define an alias for the nested namespace.
using Project = PC.MyCompany.Project;
class A 
{
void M()
{
// Use the alias
Project.MyClass mc = new Project.MyClass();
}
}
namespace MyCompany
{
namespace Project
{
public class MyClass{}
}
}
}
2.下面的示例显示了如何为类定义 using 指令和 using 别名：
// cs_using_directive2.cs
// Using directive.
using System;   
// Using alias for a class.
using AliasToMyClass = NameSpace1.MyClass;   
namespace NameSpace1 
{
public class MyClass 
{
public override string ToString() 
{
return "You are in NameSpace1.MyClass";
}
}
}
namespace NameSpace2 
{
class MyClass 
{
}
}
namespace NameSpace3 
{
// Using directive:
using NameSpace1;
// Using directive:
using NameSpace2;   
class MainClass
{
static void Main() 
{
AliasToMyClass somevar = new AliasToMyClass();
Console.WriteLine(somevar);
}
}
}
输出:   You are in NameSpace1.MyClass
=========================================================================================
深入讨论
1. 引言在.NET大家庭中，有不少的关键字承担了多种角色，例如new关键字就身兼数职，除了能够创建对象，在继承体系中隐藏基类成员，还在泛型声明中约束可能用作类型参数的参数，在详细讨论using的多重身份的基础上来了解.NET在语言机制上的简便与深邃。
那么，using的多重身份都体现在哪些方面呢，我们先一睹为快吧： 
· 引入命名空间 
· 创建别名 
· 强制资源清理 
下面，本文将从这几个角度来阐述using的多彩应用。2. 引入命名空间using作为引入命名空间指令的用法规则为： 
using Namespace; 
在.NET程序中，最常见的代码莫过于在程序文件的开头引入System命名空间，其原因在于System命名空间中封装了很多最基本最常用的操作，下面的代码对我们来说最为熟悉不过： 
using System; 
这样，我们在程序中就可以直接使用命名空间中的类型，而不必指定详细的类型名称。using指令可以访问嵌套命名空间。 
关于：命名空间 
命名空间是.NET程序在逻辑上的组织结构，而并非实际的物理结构，是一种避免类名冲突的方法，用于将不同的数据类型组合划分的方式。例如，在.NET中很多的基本类型都位于System命名空间，数据操作类型位于System.Data命名空间，3.误区· using类似于Java语言的import指令，都是引入命名空间（Java中称作包）这种逻辑结构；而不同于C语言中的#include指令，用于引入实际的类库， 
· using引入命名空间，并不等于编译器编译时加载该命名空间所在的程序集，程序集的加载决定于程序中对该程序集是否存在调用操作，如果代码中不存在任何调用操作则编译器将不会加载using引入命名空间所在程序集。因此，在源文件开头，引入多个命名空间，并非加载多个程序集，不会造成“过度引用”的弊端。 using为命名空间创建别名的用法规则为： 
using alias = namespace | type; 
其中namespace表示创建命名空间的别名；而type表示创建类型别名。例如，在.NET Office应用中，常常会引入Microsoft.Office.Interop.Word.dll程序集，在引入命名空间时为了避免繁琐的类型输入，我们通常为其创建别名如下： 
using MSWord = Microsoft.Office.Interop.Word; 
这样，就可以在程序中以MSWord来代替Microsoft.Office.Interop.Word前缀，如果要创建Application对象，则可以是这样， 
private static MSWord.Application ooo = new MSWord.Application(); 
同样，也可以创建类型的别名，用法为： 
using MyConsole = System.Console; 
class UsingEx 
{ 
public static void Main() 
{ 
MyConsole.WriteLine("应用了类的别名。"); 
} 
} 
而创建别名的另一个重要的原因在于同一cs文件中引入的不同命名空间中包括了相同名称的类型，为了避免出现名称冲突可以通过设定别名来解决，例如：  　　namespace Boyspace 
{ 
public class Player 
{ 
public static void Play() 
{ 
System.Console.WriteLine("Boys play football."); 
} 
} 
} 
namespace Girlspace 
{ 
public class Player 
{ 
public static void Play() 
{ 
System.Console.WriteLine("Girls play violin."); 
} 
} 
} 
以using创建别名，有效的解决了这种可能的命名冲突，尽管我们可以通过类型全名称来加以区分，但是这显然不是最佳的解决方案，using使得这一问题迎刃而解，不费丝毫功夫，同时在编码规范上看来也更加的符合编码要求。4. 强制资源清理4.1 由来 
要理解清楚使用using语句强制清理资源，就首先从了解Dispose模式说起，而要了解Dispose模式，则应首先了解.NET的垃圾回收机制。这些显然不是本文所能完成的宏论，我们只需要首先明确的是.NET提供了Dispose模式来实现显式释放和关闭对象的能力。 
Dispose模式 
Dispose模式是.NET提供的一种显式清理对象资源的约定方式，用于在.NET 中释放对象封装的非托管资源。因为非托管资源不受GC控制，对象必须调用自己的Dispose()方法来释放，这就是所谓的Dispose模式。从概念角度来看，Dispose模式就是一种强制资源清理所要遵守的约定；从实现角度来看，Dispose模式就是让要一个类型实现IDisposable接口，从而使得该类型提供一个公有的Dispose方法。 
本文不再讨论如何让一个类型实现Dispose模式来提供显示清理非托管资源的方式，而将注意集中在如何以using语句来简便的应用这种实现了Dispose模式的类型的资源清理方式。我们在内存管理与垃圾回收章节将有详细的讨论。 
using语句提供了强制清理对象资源的便捷操作方式，允许指定何时释放对象的资源，其典型应用为： 
using (Font f = new Font("Verdana", 12, FontStyle.Regular)) 
{ 
//执行文本绘制操作 
Graphics g = e.Graphics; 
Rectangle rect = new Rectangle(10, 10, 200, 200); 
g.DrawString("Try finally dispose font.", f, Brushes.Black, rect); 
}//运行结束，释放f对象资源 
在上述典型应用中，using语句在结束时会自动调用欲被清除对象的Dispose()方法。因此，该Font对象必须实现IDispose接口，才能使用using语句强制对象清理资源。我们查看其类型定义可知： 
public sealed class Font : MarshalByRefObject, ICloneable, ISerializable, IDisposable 
Font类型的确实现了IDisposeable接口，也就具有了显示回收资源的能力。然而，我们并未从上述代码中，看出任何使用Dispose方法的蛛丝马迹，这正式using语句带来的简便之处，其实质究竟怎样呢？ 
4.2 实质 
要想了解using语句的执行本质，了解编译器在背后做了哪些手脚，就必须回归到IL代码中来揭密才行： 
.method public hidebysig static void Main() cil managed 
{ 
.entrypoint 
// 代码大小 40 (0x28) 
.maxstack 4 
.locals init ([0] class [System.Drawing]System.Drawing.Font f, 
[1] bool CS$4$0000) 
IL_0000: nop 
IL_0001: ldstr "Verdana" 
IL_0006: ldc.r4 12. 
IL_000b: ldc.i4.0 
IL_000c: newobj instance void [System.Drawing]System.Drawing.Font::.ctor(string,float32, 
valuetype [System.Drawing]System.Drawing.FontStyle) 
IL_0011: stloc.0 
.try 
{ 
……部分省略…… 
} // end .try 
finally 
{ 
……部分省略…… 
IL_001f: callvirt instance void [mscorlib]System.IDisposable::Dispose() 
IL_0024: nop 
IL_0025: endfinally 
} // end handler 
IL_0026: nop 
IL_0027: ret 
} // end of method UsingDispose::Main 
显然，编译器在自动将using生成为try-finally语句，并在finally块中调用对象的Dispose方法，来清理资源。 
在.NET规范中，微软建议开放人员在调用一个类型的Dispose()或者Close()方法时，将其放在异常处理的finally块中。根据上面的分析我们可知，using语句正是隐式的调用了类型的Dispose方法，因此以下的代码和上面的示例是完全等效的： 
Font f2 = new Font("Arial", 10, FontStyle.Bold); 
try 
{ 
//执行文本绘制操作 
Graphics g = new Graphics(); 
Rectangle rect = new Rectangle(10, 10, 200, 200); 
g.DrawString("Try finally dispose font.", f2, Brushes.Black, rect); 
} 
finally 
{ 
if (f2 != null) 
((IDisposable)f2).Dispose(); 
} 
4.3 规则 
· using只能用于实现了IDisposable接口的类型，禁止为不支持IDisposable接口的类型使用using语句，否则会出现编译时错误； 
· using语句适用于清理单个非托管资源的情况，而多个非托管对象的清理最好以try-finnaly来实现，因为嵌套的using语句可能存在隐藏的Bug。内层using块引发异常时，将不能释放外层using块的对象资源。 
· using语句支持初始化多个变量，但前提是这些变量的类型必须相同，例如： 
using(Pen p1 = new Pen(Brushes.Black), p2 = new Pen(Brushes.Blue)) 
{ 
// 
} 
否则，编译将不可通过。不过，还是有变通的办法来解决这一问题，原因就是应用using语句的类型必然实现了IDisposable接口，那么就可以以下面的方式来完成初始化操作， 
using (IDisposable font = new Font("Verdana", 12, FontStyle.Regular), pen = new Pen(Brushes.Black)) 
{ 
float size = (font as Font).Size; 
Brush brush = (pen as Pen).Brush; 
} 
另一种办法就是以使用try-finally来完成，不管初始化的对象类型是否一致。 
· Dispose方法用于清理对象封装的非托管资源，而不是释放对象的内存，对象的内存依然由垃圾回收器控制。 
· 程序在达到using语句末尾时退出using块，而如果到达语句末尾之前引入异常则有可能提前退出。 
· using中初始化的对象，可以在using语句之前声明，例如： 
Font f3 = new Font("Verdana", 9, FontStyle.Regular); 
using (f3) 
{ 
//执行文本绘制操作 
}5. 结论一个简单的关键字，多种不同的应用场合。本文从比较全面的角度，诠释了using关键字在.NET中的多种用法，值得指出的是这种用法并非实现于.NET的所有高级语言，本文的情况主要局限在C#中。