1

たとえば、シングルトンの基本的な実装を考えると、次のようになります。

private static Foo instance;
private readonly static Object SyncRoot=new Object();

public static Foo Instance {
    get {
        if(instance!=null)
            return instance;

        lock(SyncRoot) {
            if(instance!=null) {
                return instance;
            }

            instance=new Foo();
            return instance;
        }
    }
}

同じアプリケーションで 2 つの異なるシングルトンを取得する状況はありますか? (リフレクション、実行、同期コンテキスト、appdomain クラス、またはその他の種類の「魔法」を使用した動的 dll ロード?)

4

4 に答える 4

3

はい、リフレクションで可能です。コードはプロパティにのみ適用され、リフレクションはFooプロパティなしでインスタンスを作成できます。

ConstructorInfo ctor = typeof(Foo).GetConstructors
        (BindingFlags.Instance | BindingFlags.NonPublic)[0];

Foo foo = (Foo) ctor.Invoke(null);
于 2013-03-02T19:36:19.923 に答える
3

「同じアプリケーション」の意味を定義する必要があります。1 つの「アプリケーション」が複数の AppDomain にまたがることができる場合、はい - 各 AppDomain は実質的に完全に個別Fooのクラスを持つことになります。同様に、リフレクションを使用してinstanceフィールドを null にリセットする信頼できるコードがある場合、非常に簡単に 2 つのインスタンスが作成されます。

var field = typeof(Foo).GetField("instance",
                                 BindingFlags.Static | BindingFlags.NonPublic);

var foo1 = Foo.Instance;
field.SetValue(null, null);
var foo2 = Foo.Instance;

foo1foo2どちらも非 null の異なる参照になります。または、gdoron の回答が述べたように、コードはリフレクションによって (おそらくプライベートな) コンストラクターを呼び出すこともできます。

単一の AppDomain 内で、意図的に問題を引き起こすものがなければ、問題はありません。

とにかく、シングルトンパターンのこの実装はお勧めしません。私は通常、静的初期化子を使用して、作業を大幅に簡素化しています。詳細については、シングルトンの実装に関する私の記事を参照してください。

于 2013-03-02T19:36:22.343 に答える
0

確かに、異なる AppDomain を使用する場合、AppDomain ごとに 1 つのインスタンスが取得されます。マルチスレッド環境の場合、使用しているロック機構にも問題があると思います。ゲッター使用でインスタンスを作成する代わりに

private static Foo Instance = new Foo();
于 2013-03-02T19:38:25.317 に答える