.NET Visual C#言語入門 > 部分クラス定義
のぶ亭『プログラミングの相談窓口』 … 様々なプログラミング問題を個別対応致します |
部分クラス定義
一つのクラスや構造体またはインターフェイスの定義を、複数のソース・ファイルに分割することができます。
各ソース ファイルには、クラス定義のセクションが含まれ、分割されたすべての部分はコンパイル時に結合されます。クラス定義を分割するのが望ましいケースは、次のような場合です。
- 公開用のメンバ関連と非公開用のメンバ関連を分割することで、クラスの利用者に対して先行して公開することができます。
- 大型プロジェクトを開発する際に、クラスを別個のファイルに分割すると、複数のプログラマが同時にそのクラスの作業を行うことができます。
- 自動生成ソースを使用する際に、ソース ファイルを再作成せずにコードをクラスに追加できます。Visual Studio では、Windows フォームや Web サービス ラッパー コードを作成するときにこのアプローチを使用します。Visual Studio によって作成されたファイルを編集せずに、これらのクラスを使用するコードを作成できます。
// クラス定義の分割は、partial修飾子で宣言します public partial class Employee { public void DoWork() { } } public partial class Employee { public void GoToLunch() { } }
解説
最終的な型を形成するためには、コンパイル時にすべての部分を使用できる必要があります。また、すべての部分で同じアクセシビリティ (パブリックやプライベートなど) を使用する必要があります。
抽象と宣言された部分がある場合、型全体が抽象と見なされます。シールと宣言された部分がある場合は、型全体がシールと見なされます。また、基本型を宣言する部分がある場合は、型全体が該当するクラスを継承します。
基本クラスを指定する部分はすべて一致する必要がありますが、基本クラスを省略する部分も基本型を継承します。部分は別の基本インターフェイスを指定でき、すべての部分宣言で示されたすべてのインターフェイスが最終的な型によって実装されます。部分定義で宣言されたクラス、構造体、インターフェイスの各メンバは、他のすべての部分で利用できます。最終的な型は、コンパイル時にすべての部分を結合して形成されます。
メモ
部分識別子は、デリゲートや列挙宣言では使用できません。
入れ子にされた型は、それを包含する型自体が partial でない場合でも、partial にできます。
class Container { partial class Nested { void Test() { } } partial class Nested { void Test2() { } } }
部分型定義の属性は、コンパイル時に結合されます。
[System.SerializableAttribute] partial class Moon { } [System.ObsoleteAttribute] partial class Moon { }
この宣言は、次の宣言と等価です。
[System.SerializableAttribute]
[System.ObsoleteAttribute]
class Moon { }
- 部分型定義に含まれる次の要素はすべて結合されます。
- XML コメント
- インターフェイス
- ジェネリック型パラメータ属性
- クラス属性
- メンバ
継承がことなる部分クラス定義
partial class Earth : Planet, IRotate { } partial class Earth : IRevolve { }
この宣言は、次の宣言と等価です。
class Earth : Planet, IRotate, IRevolve { }
制限事項
部分クラス定義の使用時には、以下の規則が適用されます。
-
同じ型の部分である部分型定義はすべて partial
で修飾する必要があります。たとえば、次のクラス宣言はエラーになります。
public partial class A { } //public class A { } // Error, partial修飾子で宣言すること
- partial修飾子は、class、struct、interface キーワードの直前にのみ配置できます。
- 入れ子の部分型は、次の部分型定義で宣言します。
partial class ClassWithNestedClass { partial class NestedClass { } } partial class ClassWithNestedClass { partial class NestedClass { } }
- 同じ型の部分である部分型定義はすべて同じアセンブリまたは同じモジュール (.exe ファイルまたは .dll ファイル) 内で定義する必要があります。部分定義は、複数のモジュールにまたがることができません。
- クラス名とジェネリック型パラメータはすべての部分型定義で一致する必要があります。ジェネリック型は partial にできます。部分宣言では、それぞれ同じパラメータ名を同じ順序で使用する必要があります。
-
以下のキーワードは、部分型定義では省略できますが、ある 1
つの部分型定義に存在する場合は、同じ型の別の部分定義で指定されているキーワードと競合できません。
- public
- private
- protected
- internal
- abstract
- sealed
- 基本クラス
- new 修飾子 (入れ子にされた部分)
- ジェネリック制約 (詳細については、「型パラメータの制約」を参照してください。)
例 1
クラス CoOrds のフィールドとコンストラクタを1つの部分クラス定義で宣言し、メンバ PrintCoOrds を別の部分クラス定義で宣言しています。public partial class CoOrds { private int x; private int y; public CoOrds(int x, int y) { this.x = x; this.y = y; } } public partial class CoOrds { public void PrintCoOrds() { System.Console.WriteLine("CoOrds: {0},{1}", x, y); } } class TestCoOrds { static void Main() { CoOrds myCoOrds = new CoOrds(10, 15); myCoOrds.PrintCoOrds(); } }
例 2
部分構造体と部分インターフェイスの例
partial interface ITest { void Interface_Test(); } partial interface ITest { void Interface_Test2(); } partial struct S1 { void Struct_Test() { } } partial struct S1 { void Struct_Test2() { } }