2012-06-01 14 views
11

¿Es posible hacer que una clase base C# sea accesible solo dentro del conjunto de biblioteca en el que está compilada, al tiempo que hace públicas otras subclases que la heredan?C# clase base privada (oculta)

Por ejemplo:

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) 
    { ... } 
} 

Aquí me gustaría la clase BaseOutput sea inaccesible a los clientes de mi biblioteca, pero permiten la subclase MyOutput sea completamente público. Sé que C# no permite que las clases base tengan un acceso más restrictivo que las subclases, pero ¿hay alguna otra forma legal de lograr el mismo efecto?

ACTUALIZACIÓN

Mi solución para esta biblioteca particular, es hacer que la clase base public y abstract, y para documentar con "No utilice esta clase base directamente". También hago el constructor de la clase base internal, lo que evita que los clientes externos usen o hereden la clase.

(Es una pena, porque otros idiomas O-O me dejan he escondido clases base.)

+0

¿por qué no haces que el constructor de 'BaseOutput' sea interno para que ningún código externo pueda heredar de él? –

+0

@mikez: Sí, eso es lo que hice, consulte la actualización anterior. –

+0

clase pública con constructor interno tal vez una mejor opción (muestra en mi respuesta) –

Respuesta

12
Desafortunadamente no

. No puede derivar una clase pública de una clase interna o privada.

Debe exponer la clase base o debe declarar todos los métodos para todas sus clases similares. Si sigue la ruta donde declara todos los métodos nuevamente, probablemente sea útil crear una clase auxiliar, que tiene la implementación real de ellos. Aún así es bastante repetitivo.

+0

Lástima. Java me deja hacer esto. –

+1

¿Por qué "desafortunadamente"? – stakx

+4

Porque a veces me habría ahorrado un poco de repetición. Por ejemplo, cuando se implementa la misma interfaz en varias clases. – CodesInChaos

5

Considere un patrón como una fachada. Para eso están allí. No creo que puedas lograr lo que requieres con herencia directa.

+0

No quiero tener que crear muchos métodos de reenvío. El objetivo de la clase base oculta es evitar la reproducción de muchos métodos (comunes). –

+1

de hecho, uno debe favorecer la composición sobre la herencia de todos modos (http: //en.wikipedia.org/wiki/Composition_over_inheritance) – jeroenh

+0

@jeroenh - Eso es exactamente lo contrario de mi punto. Quiero que la clase base implemente * la mayoría * de los métodos y variables, y quiero que cada subclase derivada implemente * lo menos posible *. –

1

Dependiendo de lo que "muchos de los métodos comunes" están haciendo puede conseguir algo de él con los métodos de extensión internas:

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

Otro enfoque es hacer que el constructor interno para evitar la derivación no intencional de esa clase:

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

    ...lots of common methods... 
} 

Esto hará que el código sea más comprensible en comparación con la clase intermedia "no realmente visible" en la jerarquía.

Cuestiones relacionadas