namespace
namespace 关键字用于声明一个范围。此命名空间范围允许您组织代码并为您提供了创建全局唯一类型的方法:
命名空间名可以是任何合法的标识符。命名空间名可以包含句号。
即使未显式声明命名空间,也会创建默认命名空间。该未命名的命名空间(有时称为全局命名空间)存在于每一个文件中。全局命名空间中的任何标识符都可用于命名的命名空间中。
命名空间隐式具有公共访问权,并且这是不可修改的。
在两个或更多的声明中定义一个命名空间是可以的。如在同一个文件中分别将两个类定义为 MyCompany 命名空间的一部分:
// keywords_namespace.cs
namespace Hunts.Test
{
class MyClass1
{
//
}
}
namespace Hunts.Test
{
class MyClass2
{
//
}
}
示例:(略)
using
using 关键字有两个主要用途:
作为指令,用于为命名空间创建别名或导入其他命名空间中定义的类型。
using namespace;
using alias = type|namespace;
// Type:您想通过 alias 表示的类型。这种做法可以用于处理在同时引用包含了相同名称的类的命名空间,并需要使用而引发的冲突。(见示例1)
// namespace:您想通过 alias 表示的命名空间。或者是一个命名空间,它包含您想在无需指定完全限定名的情况下使用的类型。
作为语句,用于定义一个范围,在此范围的末尾将释放对象。
Font myFont = new Font("Arial", 10.0f);
using (myFont)
{
// use myFont
}
示例:
下面的示例显示了如何为类定义 using 指令和 using 别名:
// using 关键字
// keywords_using.cs
using System;
namespace N1
{
class A
{
public void Test()
{
//
}
}
}
namespace N2
{
class A
{
public void Test()
{
//
}
}
}
namespace Hunts.Keywords
{
// 一般做法
//using N1;
//using N2;
using type1 = N1.A;
using type2 = N2.A;
class App
{
static void Main()
{
// 一般做法
// N1.A c1 = new N1.A();
// N2.A c2 = new N2.A();
type1 t1 = new type1();
type2 t2 = new type2();
//
}
}
}
注意:
C# 通过 .NET Framework 公共语言运行库 (CLR) 来自动释放用来存储不再需要的对象的内存。内存的释放具有不确定性;一旦 CLR 决定执行垃圾回收,就会释放内存。但是,通常最好尽快释放诸如文件句柄和网络连接这样的有限资源。
using 语句允许程序员指定使用资源的对象应当何时释放资源。为 using 语句提供的对象必须实现 IDisposable 接口。此接口提供了 Dispose 方法,该方法将释放此对象的资源。
可以在到达 using 语句的末尾时,或者在该语句结束之前引发了异常并且控制权离开语句块时,退出 using 语句。
外部别名
有时可能有必要引用具有相同完全限定类型名的程序集的两个版本,例如当需要在同一应用程序中使用程序集的两个或更多的版本时。通过使用外部程序集别名,来自每个程序集的命名空间可以在由别名命名的根级别命名空间内包装,从而可在同一文件中使用。
若要引用两个具有相同完全限定类型名的程序集,必须在命令行上指定别名,如下所示:
/r:N1=a1.dll
/r:N2=a2.dll
这将创建外部别名 N1 和 N2。若要从程序中使用这些别名,则使用 extern 关键字引用它们。例如:
extern alias N1;
extern alias N2;
每一个外部别名声明都引入一个额外的根级别命名空间,它与全局命名空间平行,而不是在全局命名空间内。因此,来自每个程序集的类型就可以通过各自的、根源于适当的名空间别名的完全限定名来引用,而不会产生多义性。
示例:
比如有程序集a1.dll:
// Assembly a1.dll:
namespace N
{
public class A {}
public class B {}
}
再引用程序集a2.dll:
Assembly a2.dll:
namespace N
{
public class B {}
public class C {}
}
那么以下的程序就会出错:
class Test
{
N.A a; // Ok
N.B b; // Error
N.C c; // Ok
}
然后使用导入外部别名的方法就可以解决这个问题:
// 先在命令行执行csc /r:X=a1.dll /r:Y=a2.dll test.cs
// 导入外部别名
extern alias X;
extern alias Y;
class Test
{
// 使用::从别名中使用真实的命名空间
X::N.A a;
X::N.B b1;
Y::N.B b2;
Y::N.C c;
}