# 内部类
概念：
	也叫==嵌套类==
	就是把一个类写在另一个类的内部
	本质上它还是类，所以仍然是[[值类型和引用类型|引用类型]]

通常用法：
	1. 给外部类当“小零件”用，不想单独暴露出去
	2. 把关系很紧密的类型写在一起，减少命名污染
	3. 配合[[成员变量和访问修饰符|访问修饰符]]控制谁能访问

语法：
```Csharp
class Outer
{
	public class Inner
	{
		
	}
}
```

案例：
```Csharp
class Person
{
	private string name = "小明";
	
	public class Pet
	{
		public void LookOwner(Person p)
		{
			cw(p.name);
		}
	}
}

Person p = new Person();
Person.Pet pet = new Person.Pet();
pet.LookOwner(p); //输出 小明
```
↑ `Pet` 是 `Person` 的内部类，所以外部使用时一般写成 `Person.Pet`

注意：
1. 更规范的说法一般是==嵌套类（nested class）==
2. ==类中的内部类如果不写访问修饰符，默认是private==
3. 外部访问时通常写 `外部类名.内部类名`
4. ==C# 的内部类不会自动绑定外部类对象==，想访问外部对象的数据，一般要把外部类对象传进去
5. 内部类主要是为了==封装和组织代码==，不是继承

----
# 分部类
概念：
	在C#里更常见的叫法是==分部类==
	用 `partial` 关键字把==同一个类拆到多个文件或多个位置==
	编译时会把这些内容==合并成同一个类==

通常用法：
	1. 一个类太长了，拆开写更清楚
	2. 自动生成代码和手写逻辑分开
	3. 多人协作时减少都挤在一个文件里的冲突

语法：
```Csharp
public partial class Player
{
	
}
```
在另一个文件里也可以继续写：
```Csharp
public partial class Player
{
	
}
```

案例：
```Csharp
//Player_Base.cs
public partial class Player
{
	public string name;
	
	public void Move()
	{
		cw("移动");
	}
}

//Player_Fight.cs
public partial class Player
{
	public int atk;
	
	public void Attack()
	{
		cw("攻击");
	}
}

Player p = new Player();
p.Move();
p.Attack();
cw(p.atk);
```
↑虽然写在两个文件里，但编译后它们还是==同一个 `Player` 类==

注意：
1. ==每一部分都要写 `partial`==，少一处都不行
2. 一般要保证它们是==同名、同命名空间==的一组类型
3. 分部类是==编译时合并==，不是继承，也不是复制出多个类
4. 很适合配合工具自动生成代码，比如“工具生成一部分，自己手写一部分”
5. `partial` 不只类能用，结构体和接口也能用，但这节先记类
6. 不要为了拆而拆，拆太碎反而更难找代码

----
# 分部方法
概念：
	分部方法就是写在==分部类==中的特殊方法
	也是用 `partial` 关键字声明
	一般是一边先声明“这里留个钩子”，另一边再决定要不要实现

通常用法：
	1. 给自动生成代码留扩展点
	2. 把“框架流程”和“自定义逻辑”拆开
	3. 某些逻辑可选，有需要时再补实现

语法：
先声明：
```Csharp
partial void OnCreated();
```
再在同一个分部类型的另一部分里实现：
```Csharp
partial void OnCreated()
{
	cw("创建完成");
}
```

案例：
```Csharp
//Player_Base.cs
public partial class Player
{
	public Player()
	{
		OnCreated();
	}
	
	partial void OnCreated();
}

//Player_Extend.cs
public partial class Player
{
	partial void OnCreated()
	{
		cw("玩家初始化完成");
	}
}
```
↑ 这种写法很适合“主逻辑在自动生成文件里，扩展逻辑在自己文件里”

注意：
1. ==分部方法只能写在分部类型里==，普通类里不能单独这么用
2. 它本质上是“声明部分”和“实现部分”配对
3. 如果只是最经典那种可选分部方法，一般写法是==没有访问修饰符、返回 `void`、不能有 `out` 参数==
4. 这种“可选分部方法”如果没写实现，==编译器会把声明和调用一起移除==
5. ==如果你给它加了访问修饰符，或者返回值不是 `void`，通常就不能再省略实现==
6. 所以记忆上可以理解成：简单钩子可以不实现，复杂正式方法通常必须实现

----
引用：
1. Microsoft Learn: [Nested types (C# Programming Guide)](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/nested-types)
2. Microsoft Learn: [Partial Classes and Members (C# Programming Guide)](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/partial-classes-and-methods)
3. Microsoft Learn: [partial type (C# Reference)](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/partial-type)
4. Microsoft Learn: [Partial member (C# Reference)](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/partial-member)

#封装
#核心
