Files
My-Notes/笔记/CSharp/核心/内部类和分部类.md
T
2026-06-18 20:01:30 +08:00

183 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 内部类
概念:
也叫==嵌套类==
就是把一个类写在另一个类的内部
本质上它还是类,所以仍然是[[值类型和引用类型|引用类型]]
通常用法:
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)
#封装
#核心