2010-07-01 13 views
6

¿Es esto posible en C# de alguna manera? Este es el caso exacto para el que lo necesito: Él (el usuario) no debe poder crear instancias de esta clase. Sin embargo, quiero poder crear instancias de esta clase dentro de mi proyecto. (por lo tanto, internamente) Otras clases deberían poder heredar de él. Quiero obligar al usuario a usar solo la clase Sound más grande. El gran "PERO": el usuario debe poder usar instancias de esta clase si se lo doy, es por eso que no puedo hacerlo interno y terminarlo. Tampoco puedo hacerlo abstracto porque quiero hacer copias yo mismo. Pensé en darle al usuario solo interfaces como IChannel, pero eso no resuelve mi problema de que no debería poder hacer una instancia de Channel. Todavía podrá ver la clase si la busca, y si es lo suficientemente aventurero, incluso intenta crear una instancia. Pero como mencioné antes: no puedo hacerlo abstracto porque necesito hacer copias internamente.Cómo crear una clase que sea abstracta, pero no internamente

¡Apreciar tu ayuda!

Respuesta

8

Debería poder declarar el constructor como interno y la clase misma como pública. Eso debería (creo) darte lo que quieres.

+0

Gracias! Lo bueno es que lo haya preguntado, porque lo pensé un poco más, y el método de interfaz habría funcionado si la interfaz fuera pública, supongo que el propio canal interno. Pero hubiera sido feo :) (interfaz adicional que nadie necesita o quiere) – Blub

+1

No estoy de acuerdo; si estuviese probando un código que dependiera de su clase, definitivamente querría una interfaz, ya que las interfaces se pueden apagar fácilmente durante la prueba unitaria. Otra cosa agradable con una interfaz es que solo expone la funcionalidad relevante para el uso público de su clase, que puede ser un subconjunto de los métodos públicos que usa internamente en la clase. –

+0

Terminé creando una interfaz, porque como clase abstracta, Channel heredó otros constructores que antes no tenía en cuenta. No quería el lastre agregado, y por otras razones resultó perfectamente. A veces simplemente golpeas con suerte :) (por ejemplo: otras clases proporcionan la implementación real para IChannel, que será interna. Esto es perfecto ya que tampoco puedes crear una instancia de una interfaz) – Blub

5

Constructor interno.

6

¿No debería un constructor internal resolver el problema? De esta forma, solo su ensamblado puede crear instancias, pero el usuario puede seguir usando instancias sin restricciones.

2

¿Solo hace que el constructor de la clase sea interno?

2

Siempre se puede controlar la creación de instancias utilizando diferentes modificadores en el constructor:

public class MyClass 
{ 
    internal MyClass() 
    { 
    } 
} 

Ahora nadie puede crear una instancia de la clase, pero si se les da una instancia que puede trabajar con él como si fuera normal.

1

Como muchas otras personas mencionaron, puede tener un constructor interno en una clase pública.

Sin embargo, proporcionaría al cliente una interfaz pública y haría que toda la clase fuera interna (o abstracta si desea que el cliente pueda subclasificarla). De esta forma, usarán la interfaz, lo que les facilitará la prueba unitaria de su código. Le dará flexibilidad para cambiar la implementación en el futuro.

0

El uso de un constructor de ámbito interno le permitirá crear subclases dentro del mismo conjunto o cualquier otro ensamblaje al que haya hecho visibles las partes internas. Sin embargo, evitará la creación de subclases en otros ensambles, ya que cada clase derivada de otra se requiere para llamar a un constructor en la clase base. Si su constructor no está disponible en función de su alcance, esto evitará que otros se deriven de su clase.

En general, no me gusta este tipo de pensamiento, sin embargo. Como desarrollador, es realmente molesto descubrir que el desarrollador de una API que estoy utilizando piensa que sabe todo sobre cómo quiero usarlo. Sí, oculte los detalles internos de la implementación si es necesario, pero permítame extender la API para hacer lo que necesito (y usted no ha pensado) y no me haga saltar por los aros para hacerlo.

Ah, y sí, cree una interfaz y utilícela como devolución. Harás que mi vida sea más fácil a largo plazo, además de que será mucho más fácil burlar tu código en mis pruebas unitarias.

0

Creo que lo que quiere es una clase con un constructor publicprotected y un método internal fábrica:

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

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

también recomiendo suavemente una revisión del diseño. Esto parece bastante extraño, como otros han señalado.

Cuestiones relacionadas