2013-03-25 5 views
5

Sto cercando di creare una classe di base Singleton generico comeCome fare un generico Singleton classe base C#

public class SingletonBase<T> where T : class, new() 
{ 
    private static object lockingObject = new object(); 
    private static T singleTonObject; 
    protected SingletonBase() 
    { 

    } 

    public static T Instance 
    { 
     get 
     { 
      return InstanceCreation(); 
     } 
    } 
    public static T InstanceCreation() 
    { 
     if(singleTonObject == null) 
     { 
      lock (lockingObject) 
      { 
        if(singleTonObject == null) 
        { 
         singleTonObject = new T(); 
        } 
      } 
     } 
     return singleTonObject; 
    } 
} 

Ma devo fare costruttore come pubblico in uno derivato.

public class Test : SingletonBase<Test> 
{ 
    public void A() 
    { 

    } 
    private Test() 
     : base() 
    { } 
} 

Errore di compilazione:

'Test' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'Test'

Come posso raggiungere questo obiettivo?

+2

Penso che questa risposta sia probabilmente abbastanza rilevante: http://stackoverflow.com/a/380771/120243 –

+0

Penso che il tuo codice di esempio sia sbagliato. Costruisce bene. Solo un'ipotesi, ma penso che tu intendessi che il tuo errore era correlato a "PermissionController", nel qual caso "PermissionController" deve avere un costruttore pubblico paramerterless per soddisfare il vincolo 'new()' su 'T'. –

+0

@AlastairPitts: - Quella risposta non è ancora singleton. –

risposta

6

Il il problema è il tuo vincolo generico where T : class, new(). Il vincolo new() richiede un costruttore pubblico senza parametri su T. Non c'è modo di aggirare questo; è necessario fornire tale costruttore in Permission Controller.

+0

+1. questa è in realtà la risposta corretta al problema originale di OP.La mia risposta ha avuto più a che fare con il modello di progettazione generale. –

+0

hmm .. OK .. Penso di aver bisogno di scegliere un'altra direzione. Grazie –

2

Eviterei questo tipo di modello generico ricorsivo. Leggere questo this blog post per una spiegazione dettagliata del motivo e dei motivi non per utilizzarlo.

Per quanto posso dire, non è necessario avere alcuna sottoclasse di SingletonBase<T>. Non riesco a vedere nulla che una sottoclasse di SingletonBase<T> possa aggiungere al tuo codice. Vorrei semplicemente riscriverlo come

public static class Singleton<T> where T : class, new() 
{ 
    ... 
} 

È quindi possibile utilizzare come

var test = Singleton<Test>.Instance; 

Se si vuole essere in grado di utilizzare Test come Singleton, crearlo come

public class Test 
{ 
    public static T Instance 
    { 
     get { return Singleton.Instance<Test>; } 
    } 
} 
+0

Presumibilmente il codice postato è un caso di test ridotto. –

+0

Potresti spiegare come pensi che il post del blog collegato si applica a questa domanda? Non lo vedo –

+0

@JasonWatkins si applica allo schema utilizzato da OP - 'class Test: Singleton '. –