2012-06-01 9 views
11

È possibile creare una classe base C# accessibile solo all'interno dell'assieme di librerie in cui è compilata, mentre rende pubbliche altre sottoclassi che ne ereditano?C# private (hidden) classe base

Ad esempio:

using System.IO; 

class BaseOutput: Stream   // Hidden base class 
{ 
    protected BaseOutput(Stream o) 
    { ... } 

    ...lots of common methods... 
} 

public class MyOutput: BaseOutput // Public subclass 
{ 
    public BaseOutput(Stream o): 
     base(o) 
    { ... } 

    public override int Write(int b) 
    { ... } 
} 

Qui vorrei classe BaseOutput di essere inaccessibile ai clienti di mia libreria, ma permettono la sottoclasse MyOutput di essere completamente pubblico. So che C# non consente alle classi base di avere un accesso più restrittivo rispetto alle sottoclassi, ma esiste un altro modo legale per ottenere lo stesso effetto?

UPDATE

La mia soluzione per questo particolare biblioteca è quello di rendere la classe base public e abstract, e di documentare con "Non utilizzare questa classe di base direttamente". Faccio anche il costruttore della classe base internal, che impedisce efficacemente ai client esterni di utilizzare o ereditare la classe.

(E 'un peccato, perché altre lingue O-O mi permetta di avere nascosto le classi di base.)

+0

perché non si rende il costruttore di 'BaseOutput' interno in modo che nessun codice esterno possa ereditarlo? –

+0

@mikez: Sì, è quello che ho fatto, vedere l'aggiornamento sopra. –

+0

public class con costruttore interno potrebbe essere un'opzione migliore (esempio nella mia risposta) –

risposta

12
non

Purtroppo. Non puoi ricavare una classe pubblica da una classe interna o privata.

È necessario esporre la classe di base oppure è necessario dichiarare tutti i metodi per tutte le classi simili. Se segui il percorso in cui dichiari nuovamente tutti i metodi, è probabilmente utile creare una classe helper, che ne ha l'effettiva implementazione. Eppure è un bel po 'di lamiera.

+0

Peccato. Java mi consente di farlo. –

+1

Perché "sfortunatamente"? – stakx

+4

Perché a volte mi avrebbe risparmiato un bel po 'di boilerplate. Ad esempio quando si implementa la stessa interfaccia in più classi. – CodesInChaos

5

Considerare uno schema come una facciata. Ecco a cosa servono. Non penso che tu possa ottenere ciò che desideri con un'eredità diretta.

+0

Non voglio creare molti metodi di inoltro. L'intero punto dietro la classe di base nascosta è di evitare la replica di molti (comuni) metodi. –

+1

in effetti, si dovrebbe comunque favorire la composizione sull'ereditarietà (http: //en.wikipedia.org/wiki/Composition_over_inheritance) – jeroenh

+0

@jeroenh - Questo è l'esatto contrario del mio punto. Voglio che la classe base implementa * la maggior parte * dei metodi e delle variabili e voglio che ogni sottoclasse derivata implementi * il meno possibile *. –

1

A seconda di ciò che "molti metodi comuni" stanno facendo è possibile ottenere alcuni di essi con metodi di estensione interne:

internal static class MyStreamExtensions 
{ 
    internal static int UsefulOne(this Stream stream) 
    { 
    return 42; 
    } 
} 

Un altro approccio è quello di rendere costruttore interna per evitare di derivazione non intenzionale da quella classe:

public class BaseOutput: Stream 
{ 
    internal BaseOutput(Stream o) 
    { ... } 

    ...lots of common methods... 
} 

Ciò renderà il codice più comprensibile rispetto alla classe intermedia "non proprio visibile" nella gerarchia.