C#高级编程(第10版) C# 6 & .NET Core 1.0 (.NET开发经典名著)
上QQ阅读APP看书,第一时间看更新

3.9 部分类

partial关键字允许把类、结构、方法或接口放在多个文件中。一般情况下,某种类型的代码生成器生成了一个类的某部分,所以把类放在多个文件中是有益的。假定要给类添加一些从工具中自动生成的内容。如果重新运行该工具,前面所做的修改就会丢失。partial关键字有助于把类分开放在两个文件中,而对不由代码生成器定义的文件进行修改。

partial关键字的用法是:把partial放在class、struct或interface关键字的前面。在下面的例子中,SampleClass类驻留在两个不同的源文件SampleClassAutogenerated.cs和SampleClass.cs中:

        //SampleClassAutogenerated.cs
        partial class SampleClass
        {
          public void MethodOne() { }
        }
        //SampleClass.cs
        partial class SampleClass
        {
          public void MethodTwo() { }
        }

编译包含这两个源文件的项目时,会创建一个SampleClass类,它有两个方法MethodOne()和MethodTwo()。

如果声明类时使用了下面的关键字,则这些关键字就必须应用于同一个类的所有部分:

● public

● private

● protected

● internal

● abstract

● sealed

● new

● 一般约束

在嵌套的类型中,只要partial关键字位于class关键字的前面,就可以嵌套部分类。在把部分类编译到类型中时,属性、XML注释、接口、泛型类型的参数属性和成员会合并。有如下两个源文件:

        // SampleClassAutogenerated.cs
        [CustomAttribute]
        partial class SampleClass: SampleBaseClass, ISampleClass
        {
          public void MethodOne() { }
        }
        // SampleClass.cs
        [AnotherAttribute]
        partial class SampleClass: IOtherSampleClass
        {
          public void MethodTwo() { }
        }

编译后,等价的源文件变成:

        [CustomAttribute]
        [AnotherAttribute]
        partial class SampleClass: SampleBaseClass, ISampleClass, IOtherSampleClass
        {
          public void MethodOne() { }
          public void MethodTwo() { }
        }

注意:尽管partial关键字很容易创建跨多个文件的巨大的类,且不同的开发人员处理同一个类的不同文件,但该关键字并不用于这个目的。在这种情况下,最好把大类拆分成几个小类,一个类只用于一个目的。

部分类可以包含部分方法。如果生成的代码应该调用可能不存在的方法,这就是非常有用的。扩展部分类的程序员可以决定创建部分方法的自定义实现代码,或者什么也不做。下面的代码片段包含一个部分类,其方法MethodOne调用APartialMethod方法。APartialMethod方法用partial关键字声明;因此不需要任何实现代码。如果没有实现代码,编译器将删除这个方法调用:

        //SampleClassAutogenerated.cs
        partial class SampleClass
        {
          public void MethodOne()
          {
            APartialMethod();
          }
          public partial void APartialMethod();
        }

部分方法的实现可以放在部分类的任何其他地方,如下面的代码片段所示。有了这个方法,编译器就在MethodOne内创建代码,调用这里声明的APartialMethod:

        // SampleClass.cs
        partial class SampleClass: IOtherSampleClass
        {
          public void APartialMethod()
          {
            // implementation of APartialMethod
          }
        }

部分方法必须是void类型,否则编译器在没有实现代码的情况下无法删除调用。