Creo que estás mezclando preocupaciones aquí, y C# tiene la culpa, en realidad (y Java antes).
La herencia debe servir como un mecanismo de categorización, mientras que a menudo se usa para la reutilización de código.
Para la reutilización de código, siempre se ha sabido que la composición supera la herencia. El problema con C# es que nos da una manera tan fácil para heredar:
class MyClass : MyReusedClass { }
Pero con el fin de componer, tenemos que hacerlo por nosotros mismos:
class MyClass {
MyReusedClass _reused;
// need to expose all the methods from MyReusedClass and delegate to _reused
}
Lo que falta es un constructo como a trait (pdf), que llevará la composición al mismo nivel de usabilidad que la herencia.
Hay investigaciones sobre traits in C# (pdf), y sería algo como esto:
class MyClass {
uses { MyTrait; }
}
Aunque me gustaría ver another model (la de Perl 6 funciones).
ACTUALIZACIÓN:
Como nota al margen, el idioma Oxygene tiene a feature que le permite delegar todos los miembros de una interfaz a una propiedad de miembro que implementa esa interfaz:
type
MyClass = class(IReusable)
private
property Reused : IReusable := new MyReusedClass(); readonly;
implements public IReusable;
end;
Aquí, todo los miembros de la interfaz de IReusable
estarán expuestos a través de MyClass
y todos delegarán en la propiedad Reused
. Sin embargo, hay algunos problems con este enfoque.
Otra actualización:
he comenzado a implementar este concepto composición automática en C#: echar un vistazo a NRoles.
Gracias. Pero, ¿por qué los miembros de una clase interna no deberían considerarse internos, excepto cuando se expongan a través de una subclase pública? Creo que eso tiene sentido. – David
Gracias por su respuesta detallada y sugerencia para usar la composición. ¿Estoy en lo cierto al pensar que la respuesta a mi pregunta es más 'porque C# no se creó de esa manera' que 'porque sería una cosa estúpida de hacer'? – David
Es una cuestión de convención. Si está buscando cambiar el alcance de la clase a través de la herencia, simplemente no puede alterar las reglas para hacer que algo sea más accesible. Interna específicamente debe usarse para hacer que algo sea accesible para todas las clases en un ensamblado. Cambiar el alcance a público viola esto, haciendo que una subclase esté disponible para otros ensamblajes. Un buen uso de una clase interna es proteger las preocupaciones del marco central, por ejemplo.Si insiste en que su clase interna debería estar accesible fuera del ensamblado, probablemente no debería usar el modificador interno. –