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

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

川俣 晶
2009/11/16

8.5 静的クラス(Static Class)

 静的クラスは、デザインパターンでいうところの「シングルトンパターン」を言語仕様レベルで記述するための新しい構文である。

 シングルトンとは、1つしか存在することができないオブジェクトを意味する。Javaで実装する場合は、要求されたときに必ず同じインスタンスを返す仕組みで実現するが、C#では静的なメンバーだけで構成されるクラスを使って実現するのが一般的であるようだ。また、それが可能であるように、C#は静的なメンバーを支援するための機能が強化されている。

 さらに、あるクラスのオブジェクトがシングルトンであることを貫徹するためには、そのクラスに「インスタンス化できない」という制約を付加する必要がある。これを実現するために、C# 1.xではprivateなコンストラクタを記述するという方法が提供されていた。

 しかし、これは便利ともわかりやすいともいえない。本来不要のコンストラクタを書かなければならない手間も無駄であるし、「インスタンス化させない」という意図を実現するために「インスタンス化されたときに実行されるコンストラクタを書く」というのも矛盾した対処である。

 そこで、C# 3.0では、よりわかりやすい簡潔な構文で、インスタンス化できないクラスを記述できるようになった。クラス宣言の際に、staticキーワードを付けるだけである(リスト8.6参照)。

using System;

static class Sample // 静的クラス
{
}

class Program
{
  static void Main(string[] args)
  {
    Console.WriteLine(new Sample()); // newはコンパイルエラーになる
  }
}
リスト8.6 静的クラスの例

 このコードをコンパイルすると、インスタンス化(new)を行っている行で、

 静的クラス 'Sample' のインスタンスを作成することはできません。

というエラーが起きて、インスタンスの作成が拒絶される。クラス宣言に付いたstaticキーワードをはずすと、インスタンスは作成可能になる。

 さて、このような機能を実現する短縮構文をわざわざ用意する意義がどれぐらいあるのだろうか?

 C# 1.x時代の感覚ではあまり使用頻度は高くなさそうに思えるかもしれない。しかし、C# 3.0では、出番が増える可能性が考えられる。たとえば、クラスは単なる入れ物として使われるケースが増えるということを第1章「1.5 後退するクラスの立場」などで説明した。その際、入れ物は本当にシンプルな入れ物でよいことが多く、インスタンス化を必要としないことも多いのである。

 たとえば、リスト8.4は同人ソフトのコードの一部の抜粋だが、まさにインスタンス化を必要としない入れ物の一例である(実は、リリースされたクラスのソースコードにはstaticを付け忘れたが、それはナイショである)。

 また、メソッドが主役となった結果として、ほかのメソッドから共通に利用されるメソッドを集めたクラスというものも典型的なパターンとしてよく出てくる。

 この場合、提供されるのは素のメソッドそのものなので、クラスそのものがインスタンス化されることはないし、する意味もない。リスト8.7は同じ同人ソフトから抜粋したコードの一例である(これも、リリースされたソースコードにはstaticを付け忘れているが、それもナイショである)。

public static class General
{
   …

  // 場所間の移動メニューを表示する
  public static bool MoveMenu()
  {
     …
  }

  // ゲーム内で祭日として扱われる日であるかを判定する
  public static bool Is祭日(DateTime dateTime)
  {
     …
  }

   …
}
リスト8.7 メソッドの入れ物に徹したクラスの例

 もちろん、このようなクラスは昔から存在していた。「ユーティリティクラス」といった名前で呼ばれていたものにほかならない。それにもかかわらず、C# 3.0の時代になってそれを実現する専用の構文が与えられるようになったのは、これが「特殊なクラスの使い方」ではなく、「頻出する典型的な使い方」に変化したからだろう。

【Exercise】練習問題

 部分クラスの説明として間違っているものを選べ。

  1. ASP.NETで活用されている
  2. Windowsフォームで活用されている
  3. 定義が複数に分かれてもクラスの数は1つである
  4. 1つのクラスの定義が別のソースファイルにあってもよい
  5. 分割されたすべてのクラス定義にpartialキーワードを付加する必要はない

 ◎解答:「 5 」(この行をマウスで選択してください)End of Article


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

更新履歴
【2009/11/24】 本ページの練習問題の選択肢において以下のような誤りがありました。お詫びして訂正させていただきます。

5. 分割されたすべてのクラス定義にpartialキーワードを付加する必要がある
5. 分割されたすべてのクラス定義にpartialキーワードを付加する必要はない



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 記事ランキング

本日 月間