ITコンサルの日常

ITコンサル会社に勤務する普通のITエンジニアの日常です。

staticクラス

プログラミングC# p82

C#では、インスタンス化できないクラス(staticクラス)を作成できます。

using System;

static class StaticClass
{
        static void main(string[] args)
        {
                StaticClass sc = new StaticClass();
        }

        static void sMethod()
        {
                Console.WriteLine("static method.");
        }
}

これをコンパイルするとこうなる。

StaticClass.cs(7,3): error CS0723: スタティック型 'StaticClass'
        の変数を宣言することはできません
StaticClass.cs(7,20): error CS0712: 静的クラス 'StaticClass'
        のインスタンスを作成することはできません。

他の言語であれば、コンストラクタをprivate宣言することでしょう。
ちなみにRubyでやってみたらこうなりました。

class StaticClass
    def initialize
        puts("StaticClass initialized.")
    end
    private :initialize
end

sc = StaticClass.new

結果はこう。

StaticClass initialized.

あれ?privateなのに??
Rubyリファレンスマニュアル / クラス/メソッドの定義 / 呼び出し制限によると、

ただし initialize という名前のメソッドと initialize_copy(ruby 1.8 feature)という名前のメソッドは定義する場所に関係なく常に private になります。

元々どうあがいてもprivateらしい。
ってことは、例外でもスローするようにするしかないかなぁ。

class StaticClass
        def initialize
                # puts("StaticClass initialized.")
                raise("StaticClass cannot create.")
        end
        private :initialize
end

sc = StaticClass.new

これの結果はこう。

StaticClass2.rb:4:in `raise': StaticClass cannot create. (RuntimeError)
        from StaticClass2.rb:4:in `initialize'
        from StaticClass2.rb:9:in `new'
        from StaticClass2.rb:9:in `
'

当然のごとく落ちます。
念のためJava

class StaticClass
{
        private StaticClass()
        {
        }
}

public class StaticClass2
{
        public static void main(String[] args)
        {
                StaticClass sc = new StaticClass();
        }
}

コンパイルの結果こうなります。

StaticClass2.java:12: StaticClass() は StaticClass で private アクセスされます。

                StaticClass sc = new StaticClass();

期待通り。これはSingletonパターンとかで用いられている常套句ですよね。
というわけで、またもや(?)C#はちょっと便利な機能を持っているというお話でした。