連載:[完全版]究極のC#プログラミング

Chapter8 部分クラスと静的クラス

川俣 晶
2009/11/16


 本記事は、(株)技術評論社が発行する書籍『[完全版]究極のC#プログラミング ― 新スタイルによる実践的コーディング』から、許可を得て転載しています。
 同書籍は、もともと本フォーラムにて連載していた『C# 2.0入門』、『C# 3.0入門』の記事を整理統合し、加筆、修正されたものです。

手元でまとめて読みたい方は、ぜひ書店などにてお買い求めください。

 【注意】本記事は、書籍の内容を改変することなく、そのまま転載したものです。このため用字用語の統一ルールなどは@ITのそれとは一致しません。あらかじめご了承ください。

8.1 部分クラス(Partial Class)

 以前、Webサイト@ITにC# 1.xの入門連載を書いていたとき、eventの機能を解説する際に、GUIのイベント処理を例題に取り上げないで、コンソールアプリケーションを使っているのはおかしいという読者の感想があった。eventとはマウスをクリックしたなどのイベント処理を行うための機能であり、それを例題として取り上げないのは直感的にわかりにくいという意見だろう。

 しかし、そのように考えるのは適切ではない。なぜかといえば、GUIのイベント処理を例題として使うことには1つの明確なデメリットがあり、コンソールアプリケーションを例題に使うことには2つの明確なメリットがあると判断したからだ。

 具体的なデメリットは次のようなものだ。

  • eventはGUIのイベント処理以外でも使われるにもかかわらず、それを行うための機能という先入観を与えかねない

 そして、メリットは次のとおりである。

  • eventはGUIのイベント処理のための機能という先入観を与えないどころか、むしろ明確に否定する
  • GUIのソースコードには本質的にeventとは関係のないコードが多く入り込み、サンプルコードがわかりにくくなるが、コンソールアプリケーションではそのようなコードが少ない

 さて、ここで扱う「部分クラス」の事情もこれに似ている。部分クラスが最も的確に利用されるわかりやすい事例は、Windowsフォームの自動生成コードの分離など、GUIにかかわるプログラムだろう。しかし、それは部分クラスの1つの使い方でしかなく、そのための機能という先入観を持つことは好ましくない。そこで、ここでもコンソールアプリケーションを使ってサンプルを見ていくことにしよう。

 部分クラスが持つ機能はそれほど難しいものではない。次のひと言で9割の説明は終わってしまう。

  • クラス、構造体、インターフェースの宣言を複数の固まりに分割できる(ただし、1回のコンパイルで同時に処理される範囲内で)

 単に分割できるだけでは、そのありがたみがあまりわからないだろう。分割の結果、生ずる具体的なメリットは次のとおりである。

  • 宣言を複数のソースファイルに分割して書き込める

 それによってもたらされる具体的な効能は次のようなものだ。

  • 自動生成されるコードとプログラマーが記述するコードをスマートに混在できる
  • 巨大なクラスを複数のソースファイルに分割して記述できる

 このような効能に対する疑問はあると思うが、それは後に取り上げるとして、まずは具体的な使用例を見てみよう。

 リスト8.1リスト8.2は、SampleClassという名前のクラスを、部分クラスの機能を使って2つのソースファイル(Program.csとp1.cs)に分けて記述した例である。

using System;

partial class SampleClass // 部分クラス(SampleClassの一部)
{
  public static void SayHello()
  {
    say("Hello!");
  }
}

class Program
{
  static void Main(string[] args)
  {
    SampleClass.SayHello(); // 出力:Hello!
  }
}
リスト8.1 Program.cs

using System;

partial class SampleClass // 部分クラス(SampleClassの一部)
{
  private static void say(string message)
  {
    Console.WriteLine(message);
  }
}
リスト8.2 p1.cs

 これを見るとわかるとおり、SampleClassというクラスの宣言がどちらにもあり、それぞれclassキーワードの手前に「partial」というキーワードが書かれている。ちなみに、partialは予約語ではないので、ほかの箇所でこの名前を変数などとして使っても問題はない。

 さて、ここで注目すべき点は、privateとして宣言したsayメソッドを、別のソースファイル上のSayHelloメソッドから呼び出している点である。このような呼び出しは、C# 1.xではできないものだった(delegate型の値としてメソッドを受け渡せば呼び出せたが、直接は呼び出せない)。

 しかし、これらのサンプルコードはコンパイルでき、実行できる。なぜなら、一見2つに見えるリスト8.1リスト8.2のクラスの宣言は、実はpartialキーワードの効能により、1つのクラス宣言として扱われるからである。

 それが意味するところは、コンパイルにより作成した実行ファイルを.NET Reflectorで逆コンパイルして調べると明瞭にわかる(リスト8.3参照)。

internal class SampleClass
{
  // Methods
  private static void say(string message)
  {
    Console.WriteLine(message);
  }

  public static void SayHello()
  {
    say("Hello!");
  }
}
リスト8.3 .NET Reflectorで逆コンパイルしたSampleClassクラス

 つまり、SampleClassはコード上で2つに分かれて宣言されているだけで、内部的には「たった1つのクラス」として生成されているわけである。


 INDEX
  [完全版]究極のC#プログラミング
  Chapter8 部分クラスと静的クラス
  1.8.1 部分クラス(Partial Class)
    2.8.2 自動生成コードと安全に共存する
    3.8.3 リフレクションと部分クラス
    4.8.4 部分クラスを使ううえでの注意点
    5.8.5 静的クラス(Static Class)/【Exercise】練習問題
 
インデックス・ページヘ  「[完全版]究極のC#プログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間