2009-08-09 10 views
9

私はC#を使用しています。私は任意のC#.netプロジェクト(デスクトップまたはWebベース)に含めることができるクラスを作成しましたが、そのクラスのアプリケーションでは10個のオブジェクトしか作成されません。オブジェクトインスタンスが10を超えて作成された場合は、エラーが返されるか、単純な動作ができません。クラスのインスタンス作成を制限しますか?

私はDLLに私のクラスをバンドルして、任意のアプリケーション に含めるよmyclass.csいかなる プロジェクト内のファイルまたは

  • を含めます二つの状況、

    1. がある場合もあります

    アプリケーション内に10個以上のインスタンスが作成されている場合は、どちらの場合でもエラーが発生します。

    この質問は私の先生から聞いてきましたが、私はインターネット上の回答を検索するように言いましたが、私は試しましたが、この問題の解決策が見つかった場所はありませんでした。

    もしそうなら、それは可能でしょうか?私はあなたがmultiton patternのいくつかのフォームをしたいと考えてい

    おかげ

  • +0

    私はあなたが正しいと思っていますが、十分に特権のあるコードは、常に制限をバイパスすることができます。 – CurtainDog

    答えて

    17

    作成されたインスタンス数で静的変数を保持します。オブジェクトの構築ごとにその数を増やします。オブジェクトをIDisposableにして、Dispose()を呼び出すたびにその番号を減らします。これをスレッドセーフにするには、Interlocked.Increment()およびInterlocked.Decrement()を使用して、++および - の代わりにこの変数の値を変更します。

    +0

    デストラクタを使用する方がより防御的です。 – Dykam

    +0

    これは、一定数のインスタンスを作成できるようにするシングルトンパターンのバリエーションとほぼ同じです。 –

    +7

    ダイカム:これはC#です。 C#はデストラクタを持たず、非決定的ファイナライザを持っています。ファイナライザでカウントを減らすと、クラスがすべてスコープから外れたが、まだガベージコレクションされていない場合や、それ以上オブジェクトを作成できない場合には、自分自身を設定することができます。 –

    8

    マルチトンパターンはシングルトンパターンのバリエーションですが、オブジェクトのn個のインスタンスが可能です。シングルトンクラスが単一インスタンスを保持するための静的変数を持つように、マルチスレッドは、インスタンスへのアクセス方法に応じて、静的配列またはインスタンスマップで実装されることがよくあります。マップを使用すると、インスタンスにStringキーを提供して名前を付けることができます。

    +0

    はい、あなたはそれを言うことができますが、私はそれが15または20などまで変化する可能性のある10のインスタンスまで制限したいと思っています。 – Prashant

    +0

    マルチトンではまだ可能です。配列を使用するのではなく、サイズ変更可能なコンテナを使用します。 –

    +0

    したがって、クラス内の静的変数を維持することは最近の「パターン」ですか? –

    7

    factory patternを使用するだけで、作成されたインスタンス数のカウンタを使用する必要があります。その後、ファクトリメソッドは例外/戻り値nullをスローします。

    例:

    public class Foobar 
    { 
        private static int numInstances = 0; 
    
        public static Foobar CreateFoobar() 
        { 
         if (numInstances++ < 10) 
         { 
          return new Foobar(); 
         } 
    
         return null; 
        } 
    
        protected Foobar() 
        { 
         ... 
        } 
    } 
    

    上記の方法は、シングル・インスタンス・アプリケーションのために完璧にうまく動作しますが、マルチインスタンスのアプリケーションのために、あなたはおそらくsemaphore(実装がSystem.Threadingに存在する使用したいと思います)これは正確にこの種の状況(リソース/オブジェクトへのアクセスを制限する)を意図したものです。ほぼ同時に要求されているクラスの複数のインスタンスの問題を回避し、カウントのチェックに失敗します。

    +0

    これをFactoryに配置する唯一の問題は、アプリケーションが必要とするインスタンスの数が分かっているため、Factoryがアプリケーションの特定の実装に結びついているため、Factoryを再利用できなくなることです。 –

    +0

    @Thomas Owens:それはOPの問題ですが、彼はいつも抽象的な工場パターンを使用できます。 :) – Noldorin

    +1

    「numInstances」はいつ、どのように減少しましたか? –

    0

    新しいオブジェクトをインスタンス化するときにのstatic整数を作成して更新します。

    class YourClass 
    { 
        static int Count = 0; 
    
        public YourClass() 
        { 
         Count++; 
         if(Count > 10) 
         { 
          //throw exception 
         } 
        } 
    } 
    
    +1

    スレッドセーフではなく、各初期化時にCountを2回インクリメントしています。 –

    +0

    はい、スレッドセーフではありませんが、ポイントを取得するのは簡単な例です。 そして、私は二倍の増分を修正しました。ありがとうございました:D – bufferz

    +2

    また、減算することはありません。 –

    0

    も(アプリケーションドメインに類似)の静的アンロードメソッドを作成するクラスの静的カウンターを取り、カウント> 10

    0

    場合、インスタンスを廃棄するために、あなたのクラスのコンストラクタで例外を投げます。 Unloadメソッドは、Interlocked.Decrementを使用してカウンタを減らし、インスタンスを破棄するIDisposableの実装を呼び出します。

    (あなたは、あなたが管理するインスタンス内のリソースを持っているインスタンスの数を制限する場合、私はと仮定しています。)

    あなたはまた、ファクトリクラスが異なるの制限インスタンスのために再使用できるようにジェネリックを使用することができますクラス。制約を使用して、インスタンスにIDisposibleを実装し、デフォルトコンストラクタを持たせる必要があります。また、実際のインスタンスを返す非静的なプロパティを提供します。

    
    public class foo : IDisposable 
        { 
        public foo() { ; } 
        public string Name; 
    
        public void Dispose() { ; } 
        // Real class would free up instance resources 
        } 
    
    
        LimitedInstance<foo> li = LimitedInstance<foo>.CreateInstance(); 
    
        li.Instance.Name = "Friendly Name for instance"; 
        // do stuff with li 
    
        LimitedInstance<foo>.UnloadInstance(ref li); 
    

    唯一の問題は、あなたがC#で代入演算子をオーバーロードすることはできませんです。あなたは次の操作を行うのであれば:

    
        li = null; 
    

    代わりのアンロードメソッドを呼び出して、インスタンスはヒープ上に残り、インスタンスの数にあなたのカウンタをGCが発生するまで文句を言わない、デクリメントさ。

    関連する問題