文章目录
8. 命名空间namespace
8.1 命名空间namespace
什么是命名空间?
命名空间类似于Java中的包,它包含了一系列不同名称的类和其他命名空间,可以看作是对类和功能的一个分类,不同的命名空间下的程序需要使用这些功能时需要引用该命名空间才能使用。例如在C#中System
命名空间就包含了一系列常用的类和函数,除了这些,它内部还包含了常用集合的命名空间Collections
及其他命名空间。
命名空间的作用是什么?
一个命名空间可以装入许多不同的类、接口等等,它就像一个工具箱,包含了许多各种各样的工具。在不同的命名空间中,可以实现同样名称的类、接口等,因为他们相当于存在不同的工具箱内;同一命名空间则不允许出现同名的类、接口等,就宛如同一个工具箱中出现多个一摸一样的工具是无意义的。
内部类和命名空间都可以往其中写入不同的类、接口等,为什么不使用内部类的写法替换命名空间?
内部类一般是与外围类有着一定逻辑关系的类,访问内部类通常必须要通过外围类实例进行访问,他的可访问性也与外围类相关,并且内部类只能书写在外围类之中,所以通常而言只能写在一个文件内(除分部类的情况外);命名空间则一般包裹着同一类或具有一系列相近功能的类、接口等,他没有可访问性的概念,命名空间的类可以写在同一文件或不同文件中,只需要处于同一命名空间即可,使用命名空间中的类只需要引入命名空间即可,使用命名空间也更加便于管理相关类和接口等。
在具体使用上,命名空间就像是文件夹,文件夹中可以放各种各样不同文件,而内部类则相当于文件中的一部分内容,例如Excel文件中的一个分页,他无法替代命名空间就如一个文件无法替代一个文件夹一样。
如何声明命名空间?
C#命名空间的声明有两种方式,一种是用大括号{}
包裹,另一种则是直接使用分号;
将整个文件看作一个命名空间。
用括号包裹使用举例:
namespace NamespaceStudy
{
public class TestNamespace1
{
public TestNamespace1()
{
Console.WriteLine("TestNamespace1");
}
}
}
上面代码也等价于用分号结尾的声明:
namespace NamespaceStudy;
public class TestNamespace1
{
public TestNamespace1()
{
Console.WriteLine("TestNamespace1");
}
}
但是使用分号结尾将使这个文件不能声明其他任何的命名空间,是用括号结尾则可以在命名空间内嵌入新的命名空间:
namespace NamespaceStudy
{
public class TestNamespace1{
... }
//新的命名空间
namespace NamespaceStudy2
{
public class TestNamespace2
{
public TestNamespace2()
{
Console.WriteLine("TestNamespace2");
}
}
}
}
使用分号在内部想要再添加一个命名空间时将会报错:
如何使用命名空间中的类和接口?
使用命名空间中的类和接口的方法同样有两种,一种是通过using
关键字引入后直接使用,另一种则是显式使用,需要用命名空间名.类名或接口名
进行使用,例如使用上面代码中的TestNamespace1
类进行实例化,可以有以下两种写法:
using NamespaceStudy;//引入命名空间
namespace CSharp
{
internal class Program
{
static void Main(string[] args)
{
TestNamespace1 testNamespace1 = new();//进行实例化
}
}
}
namespace CSharp
{
internal class Program
{
static void Main(string[] args)
{
NamespaceStudy.TestNamespace1 testNamespace1 = new();//直接进行显式使用
}
}
}
但是对于不同命名空间中出现的同名类或接口,必须显式使用,否则编译器将无法理解他需要具体使用那个命名空间中的类或接口。
8.2 using关键字
using关键字除了单纯引入命名空间外还有什么用处?
using
最常用的就是为当前文件引入命名空间,但除此之外,它还具有全局引入global using
(在整个程序集当中所有的文件都引入该命名空间)、静态引入using static
(使用该方法引入的命名空间中的静态类和嵌套类型等可以直接进行访问)、using 别名
(可以对引入的命名空间或类型取一个别名,让这个文件中任何地方都可以通过别名访问对应内容)。
global using全局引入
全局引入的命名空间只需要在一个位置引入,整个程序集都可以使用,例如将命名空间视为饮水机,全局引用则是小区直接购入公共饮水机,整个小区居民都可以使用,普通引用则是小区某一居民单独买一台饮水机回家,只有他家里人才能使用。
在VS创建项目时,许多的命名空间已经被自动设置为全局引入(如System
、System.Collections.Generic
等等),只需要在我们程序中点击小箭头就可以看见自动全局引入的命名空间:
同时可以进行手动引入,例如我们在任意文件中写入全局引用global using NamespaceStudy;
,此时会发现即使没有在文件中引入这个命名空间,依然可以访问里面的类型:
using static静态引入
静态引入命名空间可以让我们不用通过指定名称就i可以访问内部静态成员,例如静态引入System.Console
,可以不显式的制定Console
类就可以访问其中的函数:
using static System.Console;
namespace CSharp_interface
{
internal class Program
{
static void Main(string[] args)
{
WriteLine("Hello World!");
}
}
}
他等效于直接显式访问WriteLine
函数:
Console.WriteLine("Hello World!");
using 取别名
取别名可以简单理解为创建一个常量名,它的值为我们引入的命名空间或类型,基础的语法为using 别名 = 命名空间或其中的类;
,例如将System.Console
取别名为CS
:using CS = System.Console;
,此时我们可以直接通过别名来使用他,效果与直接使用相同:
using CS = System.Console;
namespace CSharp_interface
{
internal class Program
{
static void Main(string[] args)
{
CS.WriteLine("Hello World!");
}
}
}