285 lines
5.1 KiB
Markdown
285 lines
5.1 KiB
Markdown
|
|
# 命名空间
|
|||
|
|
概念:
|
|||
|
|
命名空间使用 `namespace` 关键字定义
|
|||
|
|
作用是:==组织代码,避免类型名字冲突==
|
|||
|
|
|
|||
|
|
简单理解:
|
|||
|
|
命名空间就像文件夹
|
|||
|
|
同名文件放在不同文件夹里不会冲突
|
|||
|
|
同名类放在不同命名空间里也不会冲突
|
|||
|
|
|
|||
|
|
通常用法:
|
|||
|
|
1. 按功能或模块组织代码
|
|||
|
|
2. 避免不同类库之间出现同名类型冲突
|
|||
|
|
3. 让大型项目结构更清楚
|
|||
|
|
4. 配合 `using` 简化类型书写
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 语法
|
|||
|
|
传统写法:
|
|||
|
|
```csharp
|
|||
|
|
namespace 命名空间名
|
|||
|
|
{
|
|||
|
|
class 类名
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
案例:
|
|||
|
|
```csharp
|
|||
|
|
namespace Game.Character
|
|||
|
|
{
|
|||
|
|
class Player
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
文件范围命名空间写法:
|
|||
|
|
```csharp
|
|||
|
|
namespace Game.Character;
|
|||
|
|
|
|||
|
|
class Player
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
这种写法表示:
|
|||
|
|
当前文件中的类型都属于 `Game.Character` 命名空间
|
|||
|
|
|
|||
|
|
初学阶段先掌握传统大括号写法即可。
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# using 的作用
|
|||
|
|
如果类型在某个命名空间中,使用前可以写完整名称。
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
System.Console.WriteLine("Hello");
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
也可以先写 `using`:
|
|||
|
|
```csharp
|
|||
|
|
using System;
|
|||
|
|
|
|||
|
|
Console.WriteLine("Hello");
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
理解:
|
|||
|
|
`using System;` 表示引入 `System` 命名空间
|
|||
|
|
这样就不用每次都写 `System.Console`
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 避免同名冲突
|
|||
|
|
```csharp
|
|||
|
|
namespace Game
|
|||
|
|
{
|
|||
|
|
class Player
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
namespace Tool
|
|||
|
|
{
|
|||
|
|
class Player
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
这两个 `Player` 不冲突,因为它们在不同命名空间中。
|
|||
|
|
|
|||
|
|
使用完整名称:
|
|||
|
|
```csharp
|
|||
|
|
Game.Player p1 = new Game.Player();
|
|||
|
|
Tool.Player p2 = new Tool.Player();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果只写:
|
|||
|
|
```csharp
|
|||
|
|
Player p = new Player();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
编译器可能不知道你要用哪个 `Player`。
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 命名空间可以分开写
|
|||
|
|
同一个命名空间可以分布在多个文件中。
|
|||
|
|
|
|||
|
|
文件1:
|
|||
|
|
```csharp
|
|||
|
|
namespace Game
|
|||
|
|
{
|
|||
|
|
class Player
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
文件2:
|
|||
|
|
```csharp
|
|||
|
|
namespace Game
|
|||
|
|
{
|
|||
|
|
class Enemy
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
理解:
|
|||
|
|
这两个类型都属于 `Game` 命名空间
|
|||
|
|
命名空间不是文件夹本身,而是代码里的逻辑组织方式
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 命名空间可以嵌套
|
|||
|
|
```csharp
|
|||
|
|
namespace Game
|
|||
|
|
{
|
|||
|
|
namespace Character
|
|||
|
|
{
|
|||
|
|
class Player
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
更常见的写法:
|
|||
|
|
```csharp
|
|||
|
|
namespace Game.Character
|
|||
|
|
{
|
|||
|
|
class Player
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
两种写法都表示:
|
|||
|
|
`Player` 属于 `Game.Character`
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 命名空间和访问修饰符
|
|||
|
|
命名空间只是组织代码,不代表访问权限。
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
namespace Game
|
|||
|
|
{
|
|||
|
|
public class Player
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`public`、`private`、`internal` 这些才是控制访问权限的关键。
|
|||
|
|
|
|||
|
|
注意:
|
|||
|
|
1. 顶级类一般不能直接写 `private`
|
|||
|
|
2. 顶级类不写访问修饰符时,默认通常是 `internal`
|
|||
|
|
3. 命名空间不负责决定谁能访问谁
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# using 别名
|
|||
|
|
如果两个命名空间中有同名类,可以用别名简化。
|
|||
|
|
|
|||
|
|
```csharp
|
|||
|
|
using GamePlayer = Game.Player;
|
|||
|
|
using ToolPlayer = Tool.Player;
|
|||
|
|
|
|||
|
|
GamePlayer p1 = new GamePlayer();
|
|||
|
|
ToolPlayer p2 = new ToolPlayer();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
这个写法不常用,但遇到同名类型冲突时很有用。
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 常见错误
|
|||
|
|
错误1:以为文件夹名就是命名空间
|
|||
|
|
|
|||
|
|
实际:
|
|||
|
|
文件夹名和命名空间名可以一致,但不是同一个东西
|
|||
|
|
真正决定命名空间的是代码里的 `namespace`
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
错误2:忘记写 `using`
|
|||
|
|
```csharp
|
|||
|
|
Console.WriteLine("Hello");
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果没有引入 `System`,可能找不到 `Console`。
|
|||
|
|
|
|||
|
|
解决:
|
|||
|
|
```csharp
|
|||
|
|
using System;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
或者:
|
|||
|
|
```csharp
|
|||
|
|
System.Console.WriteLine("Hello");
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
错误3:同名类型不知道用哪个
|
|||
|
|
```csharp
|
|||
|
|
using Game;
|
|||
|
|
using Tool;
|
|||
|
|
|
|||
|
|
Player p = new Player();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
如果 `Game` 和 `Tool` 里都有 `Player`,这里可能会冲突。
|
|||
|
|
|
|||
|
|
解决:
|
|||
|
|
```csharp
|
|||
|
|
Game.Player p = new Game.Player();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 什么时候需要命名空间
|
|||
|
|
小练习:
|
|||
|
|
可以不太关注命名空间,直接写类也能运行
|
|||
|
|
|
|||
|
|
项目变大后:
|
|||
|
|
1. 不同模块类越来越多
|
|||
|
|
2. 第三方库越来越多
|
|||
|
|
3. 同名类型冲突概率增加
|
|||
|
|
4. 需要清晰分层和组织
|
|||
|
|
|
|||
|
|
这时就应该认真使用命名空间。
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 注意
|
|||
|
|
1. `namespace` 用来组织代码和避免命名冲突
|
|||
|
|
2. `using` 用来引入命名空间,简化类型名称
|
|||
|
|
3. 不同命名空间里可以有同名类型
|
|||
|
|
4. 使用完整类型名可以解决同名冲突
|
|||
|
|
5. 命名空间可以跨多个文件
|
|||
|
|
6. 命名空间可以嵌套,常用点号表示层级
|
|||
|
|
7. 命名空间不是访问权限控制工具
|
|||
|
|
8. 文件夹结构和命名空间通常保持一致,但语法上不是一回事
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 一句话记忆
|
|||
|
|
==namespace 负责给类型分组,using 负责把分组引进来方便使用。==
|
|||
|
|
|
|||
|
|
再压缩一点:
|
|||
|
|
==命名空间像文件夹,用来防止重名。==
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# 面试/复习时怎么说
|
|||
|
|
可以这样答:
|
|||
|
|
|
|||
|
|
“命名空间是用 `namespace` 定义的代码组织方式,主要作用是给类型分组并避免命名冲突。
|
|||
|
|
使用类型时可以写完整命名空间,也可以通过 `using` 引入命名空间来简化书写。
|
|||
|
|
命名空间可以跨多个文件,也可以嵌套,但它本身不控制访问权限。”
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
引用:
|
|||
|
|
1. Microsoft Learn: [namespace (C# Reference)](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/namespace)
|
|||
|
|
2. Microsoft Learn: [using directive (C# Reference)](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive)
|
|||
|
|
|
|||
|
|
#命名空间
|
|||
|
|
#核心
|