首页 > 编程笔记 > C#笔记 阅读:10

C# partial分布类和分布方法(附带实例)

所谓分部类型(partial type),C# 允许一个类型分开进行定义,典型的做法是分开在多个文件中。

分部类型使用的常见场景是从其他源文件自动生成分部类(例如,从 Visual Studio 模板或设计器),而这些类仍然需要人为为其编写方法。

例如:
// PaymentFormGen.cs - auto-generated
partial class PaymentForm { ... }

// PaymentForm.cs - hand-authored
partial class PaymentForm { ... }

每一个部分必须包含 partial 声明,因此以下的写法是不合法的:
partial class PaymentForm {}
class PaymentForm {}

分部类型的各个组成部分不能包含冲突的成员,例如,具有相同参数的构造器。分部类型完全由编译器处理,因此各部分在编译时必须可用,并且必须编译在同一个程序集中。

可以在多个分部类声明中指定基类,只要基类是同一个基类即可。此外,每一个分部类型组成部分可以独立指定实现的接口。

编译器并不保证分部类型声明中各个组成部分之间的字段初始化顺序。

C#分部方法

分部类型可以包含分部方法(partial method)。这些方法能够令自动生成的分部类型为手动编写的代码提供自定义钩子(hook),例如:
partial class PaymentForm  // 在自动生成的文件中
{
    ...
    partial void ValidatePayment(decimal amount);
}

partial class PaymentForm  // 在手动编写的文件中
{
    ...
    partial void ValidatePayment(decimal amount)
    {
        if (amount > 100)
            ...
    }
}
分部方法由定义和实现两部分组成。定义一般由代码生成器生成,而实现一般由手动编写。如果没有提供方法的实现,分部方法的定义会被编译器清除(调用它的代码部分也一样)。这样,自动生成的代码既可以提供钩子又不必担心代码过于臃肿。

分部方法返回值类型必须是 void,且该方法是隐式的 private 方法。分部方法不能包含 out 参数。

C#扩展分部方法

C# 9 引入的扩展分部方法(extended partial method)是为反向生成代码的情形而设计的。此时,程序员定义钩子方法而代码生成器则实现该方法。使用 Roslyn 的源代码生成器时就可能出现上述情况。我们可以向编译器提供一个程序集,并由该程序集自动生成部分代码。

当分部方法的开头是访问修饰符时,该分部方法就成为扩展分部方法:
public partial class Test
{
    public partial void M1();    // 扩展的部分方法
    private partial void M2();   // 扩展的部分方法
}
访问修饰符不仅影响方法的访问性,它还告诉编译器需要对该声明加以区别对待。

扩展分部方法必须含有实现,它不会像分部方法那样在没有实现时被编译器清除。在上述例子中,由于 M1 和 M2 两个方法指定了访问修饰符(public 和 private),因此都需要进行实现。

由于扩展分部方法无法被编译器清除,因此它们可以返回任何类型,并可以包含 out 参数:
public partial class Test
{
    public partial bool IsValid(string identifier);
    internal partial bool TryParse(string number, out int result);
}

相关文章