在.NET中using是一个多用途的关键字,除了可以引用命名空间之外,还可以用来进行异常处理。今天我们再来说说用using关键字实现的另一个功能,既定义别名,通俗的讲就是起外号!:)
using可以为命名空间或是类型定义别名,如果定义在命名空间之外,别名生效的范围就仅限于当前文件;如果定义在命名空间之内,则生效范围为当前代码块与定义别名的命名空间之交集。下面我们就来看看如何用using关键字来为命名空间定义别名:
using C = System.Console;
class Program
{
static void Main()
{
C.WriteLine("hello using!");
}
}
class Program
{
static void Main()
{
C.WriteLine("hello using!");
}
}
可以给命名空间起别名,这在一定程度上方便了我们开发,但是我们有时候会遇到一个新的问题。请看下面的例子:
//Assebly1中有如下代码:
namespace Foo.IO
{
public class Stream
{
}
}
//在Assembly2中有如下代码:
{
public class Stream
{
}
}
namespace Foo.IO
{
public class Stream
{
}
}
namespace FooIO
{
public class Stream
{
}
}
{
public class Stream
{
}
}
namespace FooIO
{
public class Stream
{
}
}
//然后我们有一个类同时引用了上面的两个程序集
using FooIO = Foo.IO;
using CusIO = Custom.IO;
class Program
{
static void Main()
{
FooIO.Stream stream1 = new FooIO.Stream();
CusIO.Stream stream2 = new CusIO.Stream();
}
}
using CusIO = Custom.IO;
class Program
{
static void Main()
{
FooIO.Stream stream1 = new FooIO.Stream();
CusIO.Stream stream2 = new CusIO.Stream();
}
}
注意上面的代码是不能通过编译的,因为编译器不知道FooIO.Stream是指assembly1下的Foo.IO.Stream(该类是通过别名引用的)还是指assembly2下的FooIO.Stream(该类是直接引用的)。这时,我们就要请出“命名空间别名限定符::”来帮忙了,这们用“::”来将上面的代码重写如下,就可以编译通过了。
using FooIO = Foo.IO;
using CusIO = Custom.IO;
class Program
{
static void Main()
{
FooIO::Stream stream1 = new FooIO::Stream();
CusIO.Stream stream2 = new CusIO.Stream();
}
}
using CusIO = Custom.IO;
class Program
{
static void Main()
{
FooIO::Stream stream1 = new FooIO::Stream();
CusIO.Stream stream2 = new CusIO.Stream();
}
}
注意,这时stream1是Assembly1中Foo.IO.Stream的一个实例。
另外还有两个比较特殊的别名符,就是全局限定符和外部限定符。分别示例如下:
全局限定符:
using System;
class Program
{
const int Console = 123;
static void Main()
{
global::System.Console.WriteLine("yes");
}
}
全局限定符是为了解决在一些大型项目中,有时命名空间的命名会和某个语法元素的名字冲突。如上例中的Console变量与System.Console。class Program
{
const int Console = 123;
static void Main()
{
global::System.Console.WriteLine("yes");
}
}
外部别名:
// Assembly1 有如下代码:
namespace FooIO
{
public class Stream
{
}
}
// Assembly2 有如下代码:
namespace FooIO
{
public class Stream
{
}
}
// 下面的代码同时使用了以上两个程序集:
extern alias AliasAsm1;
extern alias AliasAsm2;
class Program
{
static void Main()
{
AliasAsm1::FooIO.Stream stream1 = new AliasAsm1::FooIO.Stream();
AliasAsm2::FooIO.Stream stream2 = new AliasAsm2::FooIO.Stream();
}
}
请注意,以上代码如果想编辑成功,必须在类库引用属性窗口给Assembly1起一个AliasAsm1的别名,给Assembly2起AliasAsm2的别名;或是直接运行csc.exe /r:AliasAsm1= Assembly1.dll /r:AliasAsm2=Assembly2.dll Program.cs。外部别名允许我们使用定义在两个不同的程序集,但是全名一样的类(这种情况一般发生在我们需要使用一个程序集的不同版本时)。namespace FooIO
{
public class Stream
{
}
}
// Assembly2 有如下代码:
namespace FooIO
{
public class Stream
{
}
}
// 下面的代码同时使用了以上两个程序集:
extern alias AliasAsm1;
extern alias AliasAsm2;
class Program
{
static void Main()
{
AliasAsm1::FooIO.Stream stream1 = new AliasAsm1::FooIO.Stream();
AliasAsm2::FooIO.Stream stream2 = new AliasAsm2::FooIO.Stream();
}
}