- - PR -
C#のSingletonは静的クラスでlockを省略するのが一般的か
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-08-15 23:20
みなさん,こんにちは.
C#でSingletonを作る時のイディオムについて確認させてください. C#には,C++と異なり静的クラスというのがあるようですが,この静的クラスは「.Net Framework は、static type に対してthread-safe を保障する」Uchukamen C# Programming(宇宙仮面様),ならば,Singletonにする場合は,C++みたいに排他をアプリケーション側(.Net Frameworkが考える)で考える必要が無く,静的クラスにすることでお手軽にSingletonが成立すると思うのですがいかがでしょうか. | ||||||||
|
投稿日時: 2005-08-16 01:18
言語的に静的クラスがサポートされるのは 2.0 からですね。
C#でのSingletonについては、ここらへんが参考になるかと。 http://www.microsoft.com/japan/msdn/library/ja/dnpatterns/htm/ImpSingletonInCsharp.asp?frame=true 遅延インスタンス化する必要が無ければ、排他制御せずに簡単な実装でOKということです。 | ||||||||
|
投稿日時: 2005-08-16 01:38
C#は自分でコードを書いたことすらないので、僭越ながら・・・。
static class(.NET 2.0ですか?)は、クラス内で宣言される全てが staticであることを強制するためのキーワードのように見えます。 Singletonとは「あるクラスのインスタンスがひとつしかないことを保証する」 パターン(状況によってはあるクラスに互換性のある型のインスタンスかも)なので、 全てがstaticなクラスとSingletonとでは意味が変わってくると思います。
もしもstaticなオブジェクトの初期化がThread-Safetyに行われなかった場合、 クラスが初期化されるタイミングをプログラマの責任で同期化する必要が 出てくるので、それを回避するための自然な仕様と言えるでしょう。 この仕様から、
このinstanceがSingletonであると保証することができます。 また、C++だとしても、 static const Singleton *const pInstance = new Singleton; という定数は、アドレスをキャストするして更新するような強引な手段を使う ことがありえないことを前提とすれば、Singletonと言えるでしょう。 #静的に呼ばれるコンストラクタ内ではSingletonとは限らないかな? 間違っていたら、どなたかツッコミお願いします。 | ||||||||
|
投稿日時: 2005-08-16 02:38
C++では、
MyClass& myClassInstance() { static MyClass p; return p; } でシングルトンが出来ると思ってました。C#でも同じアプローチで可能だと思っていたのですが…。 | ||||||||
|
投稿日時: 2005-08-16 10:33
やってみると、スレッドセーフではないようです。
| ||||||||
|
投稿日時: 2005-08-16 13:47
これでも外部からインスタンスを生成できないようにすれば、 静的なコンストラクタ呼び出し以外からはSingletonになりますよ。 #この場合のコンストラクタ呼び出し順序は未定義だったと思うので。 static Singleton *const pInstance = new Singleton; これはC#のnewの近い形で書いてみたまでです。先頭のconstは不要でしたね。
Thread-Safetyであるのは、static領域の初期化に限った話です。 そのクラスのメソッドが同期化される意味ではないですよ。 それに、たとえ全てのメソッドが同期化されたとしても、それだけで 単純にそのクラス全体が真にThread-Safetyであるとは言い切れません。 | ||||||||
|
投稿日時: 2005-08-16 14:14
こういうの をやると、わかってくるかもしれませんね。
_________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||||||
|
投稿日時: 2005-08-18 07:37
みなさん,ありがとうございました.
ところで, 報告を忘れていましたが私が使っているのはVisual Studio 2005 のためC#2.0です. 従って,static class OKです. static classの場合,これまでのように private static readonly Singleton instance = new Singleton(); は必要ないんですよね. |