2009-08-09 17 views
9

Sto usando C#. Ho creato una classe che può essere inclusa in qualsiasi progetto C# .net (desktop o web based), ma voglio che solo 10 oggetti vengano creati in quell'applicazione della mia classe. Se istanze dell'oggetto create più di 10, allora dovrebbe dare un errore o semplice non funzionerà.Creazione di istanze limite di una classe?

Non ci possono essere due situazioni,

  1. io incluso il file myclass.cs in qualsiasi progetto o
  2. io raggrupparli in fasci mia classe in una DLL e quindi includere in qualsiasi applicazione

In entrambe le situazioni, è necessario un errore se più di 10 istanze della mia classe vengono create nell'applicazione.

Questa domanda è stata posta dal mio insegnante, mi ha detto di cercare la risposta su internet, ho provato ma non ho trovato nessuna soluzione per questo problema, non ho sentito che possiamo limitare gli oggetti?

E 'possibile, se sì allora come?

Grazie

+0

Penso che tu abbia capito bene, il codice sufficientemente privilegiato sarà sempre in grado di aggirare qualsiasi limite imposto. – CurtainDog

risposta

17

Mantieni una variabile statica con il numero di istanze create. Incrementa quel numero con ogni costruzione dell'oggetto. Rendi l'oggetto IDisposable e decrementa quel numero su ogni chiamata a Dispose(). Se si desidera che sia sicuro per i thread, utilizzare Interlocked.Increment() e Interlocked.Decrement() per modificare il valore di questa variabile anziché ++ e -.

+0

L'utilizzo di distruttori è più a prova di errore. – Dykam

+0

È quasi la stessa di una variante del pattern Singleton che consente di creare un certo numero di istanze. –

+7

Dykam: Questo è C#. C# non ha distruttori, ha finalizzatori non deterministici. Se si diminuisce il conteggio nel finalizzatore, è possibile impostare se stessi per i casi in cui tutte le classi sono cadute al di fuori del campo di applicazione, ma non sono ancora state raccolte dalla garbage collection e non è possibile creare altri oggetti. –

8

credo che si desidera una qualche forma di multiton pattern.

Il modello multiton è una variante del modello singleton, ma che consente n istanze di un oggetto. Molto simile al modo in cui la classe singleton ha una variabile statica per contenere la singola istanza, il multiton viene spesso implementato con una matrice statica o una mappa di istanze, a seconda di come si desidera accedere alle istanze - gli array consentono solo l'accesso numerico, ma utilizzando una mappa, è possibile fornire chiavi stringa alle istanze, rendendole nominative.

+0

Sì, lo si può dire, ma voglio limitare fino a 10 istanze che possono variare fino a 15 o 20 ecc .... – Prashant

+0

È ancora possibile con la multiton. Anziché utilizzare una matrice, utilizzare un contenitore ridimensionabile. –

+0

Quindi mantenere una variabile statica in una classe è un "modello" in questi giorni eh? –

7

Avrete semplicemente bisogno di usare il factory pattern con un contatore del numero di istanze create, dopo di che il metodo factory genererà un'eccezione/return null.

Esempio:

public class Foobar 
{ 
    private static int numInstances = 0; 

    public static Foobar CreateFoobar() 
    { 
     if (numInstances++ < 10) 
     { 
      return new Foobar(); 
     } 

     return null; 
    } 

    protected Foobar() 
    { 
     ... 
    } 
} 

Il metodo di cui sopra funziona perfettamente per un'applicazione singola istanza, ma per un'applicazione multi-istanza, probabilmente si vorrà utilizzare un semaphore (esiste un'implementazione in System.Threading), che è concepito proprio per questo tipo di situazione (limitando l'accesso a risorse/oggetti). Risolve il problema di istanze multiple della classe richiesta quasi contemporaneamente e il conteggio dei controlli falliva.

+0

L'unico problema con la messa in fabbrica è che la fabbrica diventa meno riutilizzabile in quanto è legata a un'implementazione specifica di un'applicazione in quanto conosce il numero di istanze necessarie per l'applicazione. –

+0

@Thomas Owens: Se questo è un problema per l'OP, può sempre usare il modello di fabbrica astratto. :) – Noldorin

+1

Quando e come vengono diminuite le "numInstances"? –

0

Vorrei creare un numero intero statico e aggiornarlo quando si crea un'istanza di un nuovo oggetto.

class YourClass 
{ 
    static int Count = 0; 

    public YourClass() 
    { 
     Count++; 
     if(Count > 10) 
     { 
      //throw exception 
     } 
    } 
} 
+1

Non è thread-safe e si sta incrementando il conteggio due volte su ciascuna inizializzazione. –

+0

Sì, non è thread-safe ma è un semplice esempio che ottiene il punto. E ho corretto i doppi incrementi, grazie: D – bufferz

+2

Inoltre non stai mai decrementando conteggio –

0

prendere un contatore statico nella classe, e gettare un'eccezione nel costruttore della classe se count> 10

0

Ad esempio lo smaltimento di creare anche un metodo di scarico statico (simile a AppDomain). Avere il metodo di scaricamento chiama l'implementazione di IDisposable che decrementa il contatore utilizzando Interlocked.Decrement e inoltre elimina l'istanza.

(sto assumendo se la limitazione del numero di casi che avete risorse nell'istanza per gestire.)

È inoltre possibile utilizzare farmaci generici per consentire la classe fabbrica per essere riutilizzato per limitare i casi di diverso classi. Utilizzare i vincoli per richiedere all'istanza di implementare IDisposible e avere un costruttore predefinito. Fornire anche una proprietà non statica per restituire l'istanza effettiva.


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); 

L'unico problema è che non si può sovraccaricare l'operatore di assegnamento in C#. Quindi, se si fa la seguente:


    li = null; 

Invece di chiamare il metodo di scarico allora l'istanza resterà sul mucchio, e il vostro contatore per numero di istanze non sarà decrementato, finché non si verifica GC.

Problemi correlati