2009-07-14 15 views
21

コンストラクタ内の別のオブジェクトへの参照を受け入れる静的クラスまたはシングルトンクラスを作成します。静的クラスは外ですが、コンストラクタでパラメータを受け入れるシングルトンを作成できるとわかりました。これまでのところ、私は文法を見つけ出すことやグーグルグーグルをすることは一切ありませんでした。これは可能ですか?もしそうなら、どうすればいいのですか?C#パラメータを受け入れるコンストラクタを持つシングルトン

最初の投稿で申し訳ありませんが、私は急いで書きました。私は私の答えがすでに回答に入っていると感じていますが、ここで私が何をしたいか明確にしています:

特定のタイプの単一インスタンス(シングルトン)を作成したいのですが、型は別のオブジェクトへの参照を保持する必要があります。

例えば、私は、StringBuilderオブジェクトを所有するSingleton "Status"クラスと、前記StringBuilderをスクリーンに書き込むために呼び出すことができるDraw()メソッドを作成したいと思うかもしれません。 Draw()メソッドは、描画するために私のGraphcisDeviceについて知る必要があります。 は、だから私はそれをこの何をしたいか:すべてのコードの上に

public class Status 
{ 
private static Status _instance; 
private StringBuilder _messages; 
private GraphicsDevice _gDevice; 

private Status(string message, GraphicsDevice device) 
{ 
    _messages.Append(message); 
    _gDevice = device; 
} 

// The following isn't thread-safe 

// This constructor part is what I'm trying to figure out 
public static Status Instance // (GraphicsDevice device) 
    { 
    get 
     { 
     if (_instance == null) 
      { 
      _instance = new Status("Test Message!", device); 
      } 
     return _instance; 
     } 
    } 

public void UpdateMessage 
... 

public void Draw() 
    { 
    // Draw my status to the screen, using _gDevice and _messages 
    } 
} 

を、私は自分のステータスシングルトンを取得し、そのUpdateMessage()メソッドを呼び出します。

private Status _status = Status.Instance; // + pass reference to GraphicsDevice 
_status.UpdateMessage("Foo!"); 

その後、私はまた、シングルトンを取得し、それを描く私のメインクラスで:

_status.Draw(); 

はい、これは私はシングルトンを取得どこでも、私は渡すことでそうする必要があることを意味私が初めてシングルトンをインスタンス化する場合に備えて、GraphicsDeviceへの参照。そして私は、例えば、サービスを他の場所に登録し、そのサービスをStatusクラスで取得するなど、シングルトンクラスのGraphicsDeviceと同じように基本的なものを取得するために、さまざまな手段を使用できます。この例はかなり工夫されています - 私はこのパターンのような何かが最初に可能であるかどうかを判断しようとしています。

+1

私が尋ねてきたことについて、はるかに優れた説明が追加されました。 –

答えて

2

あなたが説明しているのは、ジェネリックシングルトンです。それは次のようになります。

public class SingletonProvider <T> where T:new() 
{ 
    SingletonProvider() {} 

    public static T Instance 
    { 
     get { return SingletonCreator.instance; } 
    } 

    class SingletonCreator 
    { 
     static SingletonCreator() { } 

     internal static readonly T instance = new T(); 
    } 
} 

http://www.codeproject.com/KB/cs/genericsingleton.aspx

+4

アプリケーションにタイプTのインスタンスが他にないことをどのように保証できますか?これは本当にシングルトンではありません。 –

+5

私は、質問をしている人が既にそのタイプを他のものに使うことができないことを理解していると思います。彼はナイフを頼んだので、私は彼にそれをどうするか教えてくれませんでした。 –

+1

シングルトンはシングルトンとは異なるタイプですので、関係ありません。一般的なシングルトンは、シングルトンを作成するための基本クラスとして機能する場合にのみ意味をなさないと思います。 –

17

これは一般的に悪い考えと考えられているあなたは、あなたがシングルトンのようなラッパーでラッピングする予定のオブジェクト参照または型引数のいずれかを受け入れるしようとしている場合ので、そのタイプの唯一のインスタンスをAppDomainに保持することを保証することはできません。

シングルトンパターンの全体点は、そのタイプのインスタンスが1つしか存在しないように、タイプの1つのインスタンスを制御することです。インスタンスを渡すことを許可する場合、または一般的なシングルトンプロバイダを作成する場合は、インスタンスがのインスタンスであることを保証することはできません。インスタンスのみです。

私がSingletonFactory<T>を持っていて、私が工場に渡すどのタイプでもシングルトンを作成できるとしましょう。それは非常に便利だろうと私はこのような何かできるようになる:

SingletonFactory<Foo>.Instance; 

しかし、何もやってから私を停止します。

Foo foo = new Foo(); 

はおっと、それはFooのように見えるがシングルトンはもうありません私が望むだけ多くのインスタンスを作成することができます。シングルトンパターンを機能させるには、インスタンスを制限する必要がある型を完全に制御できる必要があります。これが私のSingletonFactory<T>のようなものを使用してはならない理由です。

注:オブジェクトインスタンスを受け入れる非ジェネリックシングルトンの場合も同じです。私はあなたが私の前の例から、オブジェクト参照を受け入れるシングルトンラッパーもまた悪い考えである多くの同様の理由を推論することができると確信しています。

2

あなたは、特にこのようなルックスを求めているものを、私は思う:

public sealed class Singleton { 
    static Singleton instance = null; 
    static readonly object padlock = new Object(); 
    Object o; 

    Singleton(Object _o) { 
     o = _o; 
    } 

    public static Singleton Instance(Object _o) { 
     lock (padlock) { 
      if (instance == null) { 
       instance = new Singleton(_o); 
      } 
      return instance; 
     } 
    } 
} 

Singleton s = Singleton.Instance(new Object()); 

私はすでに掲載ジェネリックバージョンはしかし、あなたが本当に欲しいものであると思われます。

1

プライベートコンストラクタとgetInstanceメソッドが必要です。このメソッドは誰がparamを受け取るべきか、コンストラクタはプライベートでなければならず、paramsも持つことができますが、getInstanceはそれを渡すべきです。 Btw、何してるの?実際の例が役立つかもしれません。あなたが行うことができます

0

ことの一つは、あなたが見つかったシングルトンのサンプルに付着し、ちょうどプロパティをさらす(セッター、必要であれば、同様にゲッターを追加)し、制限する必要がある場合 MySingleton.Instance.MyReference = new MyObject();

のようにそれを使用することができますたとえば、参照が設定される前にシングルトンオブジェクトの操作が不正である必要がある場合は、hasBeenIntializedやMyReference setterなどの内部ブール値フラグを内部的に設定できます。他のすべてのメソッドは、実行の開始時にフラグをチェックし、hasBeenInitializedがfalseの場合にメソッドが呼び出されると例外をスローします。

読み取り専用の動作が必要な場合は、hasBeenInitializedがtrueに設定されている間に誰かが別のオブジェクトを割り当てたい場合、MyReferenceセッターで例外をスローすることがあります。

関連する問題