2010-02-28 7 views
7

Dato il seguente codice client:Can A Constructor Restituisce una sottoclassifica?

var obj = new Class1(); 

C'è un modo per modificare il costruttore di Class1 in modo che sarà effettivamente restituire una sottoclasse (o qualche altra implementazione alternativo), invece?

Vorrei obj per ottenere una delle due diverse implementazioni, a seconda di alcune condizioni. Ovviamente, potrei passare all'utilizzo di un factory o di un framework DI, ma vorrei evitare di cambiare il codice del client, se possibile.

Suppongo che la risposta sia no, ma mi chiedo se c'è un modo intelligente per farlo accadere.

+4

Stiamo considerando l'aggiunta di una funzionalità "estensione nuova" che essenzialmente consente di creare un metodo di produzione statico che verrebbe chiamato quando viene utilizzato l'operatore "nuovo", analogamente ai metodi di estensione quando "." l'operatore è usato Sarebbe un bel zucchero sintattico per la fabbrica. Se si dispone di uno scenario davvero fantastico in cui questo tipo di schema sarebbe utile, mi piacerebbe vedere un esempio. –

+1

@Eric: anche se non si tratta di un esempio C#, mi sono imbattuto in una situazione in cui ciò sarebbe stato utile in C++. Sto sviluppando una libreria multipiattaforma e sarebbe davvero utile per un ABC indipendente dalla piattaforma essere in grado di restituire un'istanza di classe derivata specifica della piattaforma dal suo costruttore. Sono sicuro che ci devono essere situazioni simili da trovare quando si sviluppa con C#. – Mac

+0

@Eric Lippert - Ho uno scenario del mondo reale per te! http://blog.hackensplat.com/2010/09/construct-something-else-c.html – billpg

risposta

4

Questo non è possibile.

Soluzioni alternative includono la sostituzione del costruttore con una funzione static o (non consigliata) utilizzando un wrapper attorno alla classe base e la creazione di classi wrapping diverse.

8

è possibile sostituire il costruttore con un metodo factory, e restituire quello che vuoi, a seconda dei parametri:

public Class2 : Class1 {} 

public static Class1 CreateClass1(bool returnDerivedClass) 
{ 
    if (returnDerivedClass) 
    { 
     return new Class2(); 
    } 
    else 
    { 
     return new Class1(); 
    } 
} 
0

Per le cose come queste che si desidera controllare il pattern Factory. Inoltre, a seconda delle esigenze, suggerirei metodi generali per ridurre l'accoppiamento. La tua chiamata al costruttore della classe è l'accoppiamento più difficile che puoi avere in un programma e fa cose come scambiare l'implementazione con una seccatura, come hai scoperto tu stesso.

Leggi "Inversione di controllo" e "Iniezione di dipendenza", forse è quello che cerchi davvero.

Una bella libreria può essere trovata here.

0

Utilizzare una libreria di iniezione. Il link qui sotto presenta una grande lista di librerie iniezione là fuori e il confronto delle loro prestazioni

http://www.palmmedia.de/blog/2011/8/30/ioc-container-benchmark-performance-comparison

Vorrei suggerire, tuttavia, che le prestazioni è raramente un criterio si sceglie una libreria iniezione su, la maggior parte delle applicazioni non sarebbero istanziare il numero di oggetti che questo ragazzo ha usato nei suoi test. Sto usando NInject che fa bene il lavoro, tuttavia se dovessi iniziare un altro progetto probabilmente darei il simpleinjector, sembra che abbia tutte le funzionalità che uso in NInject e che funzioni bene nei confronti delle prestazioni.