分部类
(了解即可)
允许你将一个类、结构或接口的定义拆分到多个源文件中,这些文件在编译时会被合并成一个完整的类型定义。(这种特性在处理大型项目、自动生成代码或团队协作时特别有用。)
在 C# 中,分部类(Partial Classes) 的拆分数量并没有硬性的语法限制,你可以将一个类拆分成任意多个部分(理论上仅受限于编译器和系统资源)
语法
使用 partial 关键字标记类定义,多个部分可以分布在不同文件中:
// 文件1: Person.part1.cs
public partial class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
// 文件2: Person.part2.cs
public partial class Person
{
public void SayHello() => Console.WriteLine($"Hello, I'm {Name}.");
}
编译后效果:
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public void SayHello() => Console.WriteLine($"Hello, I'm {Name}.");
}
使用场景
- 常用于 ORM 框架(如 Entity Framework)或 UI 设计器(如 Windows Forms),将自动生成的代码与用户代码分离:
// 自动生成的代码(Form1.Designer.cs)
partial class Form1 : Form
{
private Button button1;
private void InitializeComponent() { ... }
}
// 用户代码(Form1.cs)
partial class Form1
{
public Form1()
{
InitializeComponent();
button1.Click += Button1_Click;
}
}
- 组织大型类 将复杂类按功能拆分(如将数据访问、业务逻辑、UI 处理分开):
// DataAccess.Partial.cs
partial class CustomerService
{
public void SaveCustomer(Customer customer) { ... }
}
// BusinessLogic.Partial.cs
partial class CustomerService
{
public void ValidateCustomer(Customer customer) { ... }
}
规则
- 必须标记 partial: 所有部分都要使用 partial 关键字。
- 相同的访问修饰符: 所有部分的访问修饰符(如 public、internal)必须一致。
- 相同的命名空间和类名: 所有部分必须在同一个命名空间中,且类名、泛型参数(如果有)必须相同。
- 继承与接口: 各部分可独立指定基类或实现接口,但最终类会合并所有基类和接口。
- 静态成员与嵌套类型: 可在不同部分定义静态成员或嵌套类型。
- 特性(Attributes): 各部分的特性会合并。
- 分部方法(Partial Methods): 声明和实现可分离在不同部分,若未实现则调用会被编译器移除。
注意事项
- 不能跨程序集拆分: 分部类的所有部分必须在同一个程序集中。
- 不能部分抽象或密封: 若一个部分标记为 abstract 或 sealed,则所有部分都必须一致。
- 成员不能重复定义: 同名成员(字段、属性、方法等)会导致编译错误,除非是分部方法。
- 部分类不能使用 extern: extern 关键字不能用于部分类。
分部类与分部方法
// 文件1: GeneratedCode.cs(自动生成)
public partial class OrderProcessor
{
public void ProcessOrder(Order order)
{
// 核心处理逻辑
OnProcessing(order); // 调用分部方法(可能未实现)
}
partial void OnProcessing(Order order); // 声明分部方法
}
// 文件2: UserCode.cs(用户代码)
public partial class OrderProcessor
{
partial void OnProcessing(Order order)
{
Console.WriteLine($"Processing order: {order.Id}");
}
}