2012-02-03 17 views
5
class MyClass<T> where T: new() 
{ 
    public Test() 
    { 
     var t = new T(); 
     var t = new T("blah"); // <- How to do this? 
    } 
} 

So che non è possibile come scritto, e per quanto ho capito è semplicemente non consentito (anche se non mi piacerebbe altro che sbagliarmi). La prima soluzione che viene in mente è quella di utilizzare un inizializzatore di oggetti, ma supponiamo che sia l'ultima risorsa perché in questo caso sarebbe in conflitto con altri obiettivi di oop.Istanziare un tipo generico con un costruttore sovraccarico

La mia prossima inclinazione sarebbe quella di utilizzare la riflessione, ma prima di farlo vorrei sapere se sto trascurando un modo più semplice per farlo o forse un modello di progettazione diverso che funzionerebbe meglio?

+1

Direi che Reflection è la tua unica speranza. Ma con la riflessione bisogna fare affidamento sulla convenzione piuttosto che sul controllo del tempo di compilazione che probabilmente è quello che stai cercando. Forse potresti usare una fabbrica forse, ma non riesco a vedere come una fabbrica possa essere generica e fare ancora il lavoro. Inizializzazione oggetto! = OOP. –

+0

Sono d'accordo con @ MikaelÖstberg e cerco di usare una fabbrica. – Lukazoid

+0

Ma la fabbrica potrebbe essere generica? Affronterei le stesse sfide di quello che vediamo ora nel codice. Le fabbriche dovrebbero essere concrete. –

risposta

4

Non è possibile farlo direttamente. Avrete bisogno di usare Activator.CreateInstance, ma così facendo ha tutti gli inconvenienti di riflessione, il che significa che si perde il controllo in fase di compilazione, ecc

public Test() 
{ 
    var t = (T)Activator.CreateInstance(typeof(T), (object)"blah"); 
} 
+0

Dolce, penso che sia la mia migliore opzione. L'ho usato in passato e continuavo a pensare che avrei potuto fare qualcosa di simile in fondo alla mia mente ma per qualsiasi motivo mi ero appena dimenticato e pensavo che la riflessione avrebbe richiesto un complicato codice di lettura/manutenzione complicato . Questo è abbastanza semplice però. –

3

È possibile forzare utente per darvi il modo per costruire l'oggetto da string, come questo:

internal class MyClass<T> 
    where T : new() 
{ 
    public void Test(Func<string, T> func) 
    { 
     var t = func("blah"); 
    } 
} 

Function può essere parte di construzione MyClass oggetto, in modo da non dovrà passare ogni volta che si chiama i metodi che devono creare T. In realtà con quell'aproach new() potrebbe non essere necessario.

+0

Hmm ... è interessante. Per il momento vado con la soluzione Activator.CreateInstance, ma se le prestazioni di riflessione sono inferiori alle aspettative, potrei semplicemente provare a provare questo. –

Problemi correlati