Files
My-Notes/笔记/CSharp/核心/内部类和分部类.md
T

183 lines
4.6 KiB
Markdown
Raw Normal View History

2026-06-18 20:01:30 +08:00
# 内部类
概念:
也叫==嵌套类==
就是把一个类写在另一个类的内部
本质上它还是类,所以仍然是[[值类型和引用类型|引用类型]]
通常用法:
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)
#封装
#核心