CS3L22——命名空间

本章代码关键字

1
2
3
namespace        //命名空间关键字
public //公开的类,可以被另外的工程调用
internal //内部的类,不能被其他工程调用

命名空间

命名空间是用来组织和重用代码的

作用:就像是一个工具包,类就像是一件一件的工具,都是申明在命名空间中的

命名空间是个工具包 用来管理类,在不同命名空间中允许有同名类
不同命名空间中相互使用,需要引用命名空间或指明出处,命名空间可以可以包裹命名空间

命名空间的声明

命名空间可以分开写,甚至可以分成两个文件写,但是同一命名空间内不可以有同名类(分部类可以分开声明)

基本语法如下:

1
2
3
4
5
6
namespace 命名空间名
{
class 类1 { ... }
class 类2 { ... }
// ...
}

示例:

1
2
3
4
5
6
7
8
9
10
11
namespace MyGame
{
class GameObject { }
}

//命名空间可以分开写,甚至可以分成两个文件写,但是同一命名空间内不可以有同名类
namespace MyGame
{
// class GameObject { }
class Player : GameObject { }
}

不同命名空间中允许有同名类

顾名思义,在不同命名空间中允许有同名类,但如果要同时使用它们就需要注意指明命名空间

1
2
3
4
5
6
7
8
9
namespace MyGame
{
class GameObject { }
}

namespace MyGame2
{
class GameObject { } //在不同命名空间中允许有同名类
}

命名空间可以可以包裹命名空间

命名空间里的命名空间可以理解为工具包里的小包

注意,虽然命名空间是可以嵌套的,但是如果要引用嵌套命名空间的类,
只引用父命名空间是不行的,需要在父命名空间点出子命名空间才能引用

1
2
3
4
5
6
7
8
9
10
11
12
namespace MyGame
{
namespace UI
{
class Image { }
}

namespace Game
{
class Image { }
}
}

例如如果要使用 UI​ 的 Image​,那么就需要引用 MyGame.UI

使用其他命名空间的类的方法

如果要正常使用别的命名空间的类,需要 using 命名空间名;​ 来引用命名空间,或者通过 命名空间.类名​ 指明出处来引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
namespace MyGame
{
class GameObject { }
class Player : GameObject { }

namespace UI
{
class Image { }
}

namespace Game
{
class Image { }
}
}

namespace MyGame2
{
class GameObject { } //在不同命名空间中允许有同名类
}

假设这里要引用 MyGame​ 的 GameObject​ 类,可以使用 using​ 来引用命名空间
对于引用 嵌套的命名空间 的类,需要 using 父命名空间.子命名空间;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//如果要正常使用别的命名空间的类,需要using 命名空间名; 来引用命名空间
using MyGame;
using MyGame.UI;

namespace lesson21_命名空间
{
internal class Program
{
static void Main(string[] args)
{
GameObject g = new GameObject();
Image img = new Image();
}
}
}

也可以在类名前加上命名空间来指明出处,对于引用 嵌套的命名空间 的类,需要 父命名空间.子命名空间.类名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
namespace lesson21_命名空间
{
internal class Program
{
static void Main(string[] args)
{
//或者不使用using,使用指明出处的方法
MyGame.GameObject g1 = new MyGame.GameObject();
MyGame.GameObject g2 = new MyGame.GameObject();

//引用命名空间里的命名空间的类 需要指明出处
MyGame.UI.Image img = new MyGame.UI.Image();
MyGame.Game.Image img2 = new MyGame.Game.Image();
}
}
}

注:C#10及以后会有隐式 using​ ,在 csproj​ 项目文件内设置 ImplicitUsings​ 属性为 true​ 就会开启

1
2
3
4
5
6
7
8
9
10
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>

它会隐式引用一系列常用的系统的命名空间,例如 System​ 等,以节省代码量,但该特性不适用于当前(C#9)的Unity开发

如果引用两个命名空间,而且这两个命名空间包含了两个同名的类,则直接使用同名的类就会报错,因此必须要指明出处
也可以只引用其中一个命名空间,引用命名空间的那个类就不需要再指明出处,而另一个命名空间的同名类就需要指明出处

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
namespace MyGame
{
class GameObject { }

namespace UI
{
class Image { }
}

namespace Game
{
class Image { }
}
}

namespace MyGame2
{
class GameObject { } //在不同命名空间中允许有同名类
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using MyGame;
using MyGame2;

using MyGame.UI;

namespace lesson21_命名空间
{
internal class Program
{
static void Main(string[] args)
{
MyGame.GameObject g1 = new MyGame.GameObject();
MyGame2.GameObject g2 = new MyGame2.GameObject();

Image img1 = new Image(); // 这里默认会使用MyGame.UI的Image
MyGame.Game.Image img2 = new MyGame.Game.Image() // 这样才能使用另一个命名空间的同名Image
}
}
}

关于修饰类的访问修饰符

注意!这里是修饰类的访问修饰符,和修饰类中成员的访问修饰符的作用不同

  • public​ —— 命名空间中的类,可以被外部工程调用

  • internal​ —— 只能在该程序集里使用,只能在该项目内使用,不加修饰的类,默认为 internal

    何为程序集,一个解决方案内可以有多个工程,这些工程就是一个个的程序集,不同的工程会编译为不同的可执行文件

    image

    不同的工程之间可以相互引用,引用后,就可以使用其他工程里的 public​ 类,只要命名空间写清楚

    假设工程A有一个 internal​ 类,即使 项目B 引用了 项目A ,项目B 也不能引用工程A的 internal​ 类

  • ​abstract​ —— 抽象类

  • ​sealed​ —— 密封类

  • ​partial​ —— 分部类