2010-07-01 16 views
6

Ciò è possibile in C# in qualche modo? Questo è il caso esatto di cui ho bisogno per: Lui (l'utente) non deve essere in grado di creare istanze di questa classe. Tuttavia, voglio essere in grado di creare istanze di questa classe all'interno del mio progetto. (quindi: internamente) Altre classi dovrebbero essere in grado di ereditarlo. Voglio forzare l'utente a usare solo la classe Sound più grande. Il grande "BUT": l'utente deve essere in grado di utilizzare le istanze di questa classe se glielo diamo, ecco perché non posso semplicemente renderlo interno e averne a che fare. Nemmeno posso renderlo astratto, perché voglio fare delle copie io stesso. Ho pensato di fornire all'utente solo interfacce come IChannel, ma questo non risolve il mio problema che non dovrebbe essere in grado di creare un'istanza di Channel. Sarà ancora in grado di vedere la classe se la cerca, e se è abbastanza avido cerca di creare un'istanza. Ma come ho detto prima: non riesco a renderlo astratto perché ho bisogno di fare copie internamente.Come creare una classe che sia astratta, ma non internamente

Apprezzo il tuo aiuto!

risposta

8

Dovresti essere in grado di dichiarare il costruttore come interno e la classe stessa come pubblica. Questo dovrebbe (penso) darti quello che vuoi.

+0

Grazie! La cosa buona è stata chiesta, perché ci ho pensato un po 'di più, e il metodo dell'interfaccia avrebbe funzionato se l'interfaccia fosse pubblica, e il Canale stesso interno credo. Ma sarebbe stato brutto :) (interfaccia aggiuntiva che nessuno ha bisogno o vuole) – Blub

+1

Non sono d'accordo; se stavo testando il codice che faceva affidamento sulla tua classe, avrei sicuramente bisogno di un'interfaccia, in quanto le interfacce possono essere facilmente eliminate durante il test dell'unità. Un'altra cosa carina con un'interfaccia è che espone solo le funzionalità rilevanti per l'uso pubblico della tua classe, che potrebbe essere un sottoinsieme dei metodi pubblici che usi internamente alla classe. –

+0

Ho finito per creare un'interfaccia, perché come una classe astratta Channel ha ereditato altri costruttori che non avevo preso in considerazione prima. Non volevo la zavorra aggiunta, e per altri motivi è andata alla perfezione. A volte sei semplicemente fortunato :) (ad esempio: altre classi forniscono l'effettiva implementazione per IChannel, che sarà interna. Questo è perfetto dato che non puoi creare un'istanza di un'interfaccia) – Blub

5

Costruttore interno.

6

Non dovrebbe un costruttore internal risolvere il problema? In questo modo solo l'assembly può creare istanze, ma l'utente può ancora utilizzare le istanze senza restrizioni.

2

Basta rendere interno il costruttore della classe?

2

Puoi sempre controllare la creazione esempio utilizzando diversi modificatori sul costruttore:

public class MyClass 
{ 
    internal MyClass() 
    { 
    } 
} 

Ora nessuno può istanziare la vostra classe, ma se si dà loro un esempio che può lavorare con esso come normale.

1

Come molte altre persone hanno menzionato, è possibile avere un costruttore interno in una classe pubblica.

Tuttavia, fornirei al cliente un'interfaccia pubblica e rendere l'intera classe interna (o astratta se si desidera che il client sia in grado di suddividerla). In questo modo useranno l'interfaccia, che renderà più facile per loro testare il loro codice. Vi darà la flessibilità per cambiare l'implementazione in futuro.

0

L'utilizzo di un costruttore con ambito interno consente di creare sottoclassi all'interno dello stesso assembly o di qualsiasi altro assembly a cui sono stati resi visibili internals. Impedirà la creazione di sottoclassi in altri assembly, tuttavia, poiché ogni classe derivata da un'altra è necessaria per chiamare un costruttore nella classe base. Se il tuo costruttore non è disponibile in base al suo ambito, ciò impedirà ad altri di derivare dalla tua classe.

In generale, non mi piace questo tipo di pensiero, però. Come sviluppatore è davvero fastidioso scoprire che lo sviluppatore di un'API che sto usando crede di sapere tutto su come voglio usarlo. Sì, se necessario, nascondi i dettagli interni dell'implementazione, ma per favore concedimi di estendere l'API per fare ciò di cui ho bisogno (e non hai pensato) e non farmi saltare i cerchi per farlo.

Oh, e sì, creare un'interfaccia e utilizzarla come ritorno. A lungo andare renderai più facile la mia e la tua vita, oltre a rendere molto più facile prendere in giro il tuo codice nei miei test unitari.

0

penso che ciò che si vuole è una classe public con un costruttore protected e un metodo di internal fabbrica:

public class MyClassWhichIsAbstractExceptForMe 
{ 
    // Allow derived classes but prevent public construction. 
    protected MyClassWhichIsAbstractExceptForMe() 
    { 
    } 

    // Allow internal construction 
    internal static MyClassWhichIsAbstractExceptForMe Create() 
    { 
     return new MyClassWhichIsAbstractExceptForMe(); 
    } 
} 

Ho anche consiglio delicatamente un esame del progetto. Questo sembra abbastanza strano, come altri hanno sottolineato.

Problemi correlati