Quiero escribir algo como lo siguiente:¿Cómo evitar que una clase abstracta con clases públicas derivadas se herede en otros ensambles?
internal class InternalData
{
}
public class PublicData
{
}
abstract internal class Base {
internal Base() { }
private static InternalData CreateInternalDataFromPublicData(PublicData publicData)
{
throw new NotImplementedException();
}
abstract protected void DoProcess(InternalData internalData);
public void Process(PublicData publicData)
{
InternalData internalData = CreateInternalDataFromPublicData(publicData);
DoProcess(internalData);
}
}
public sealed class Derived : Base
{
protected override void DoProcess(InternalData internalData)
{
throw new NotImplementedException();
}
}
Es decir, Base
contiene algo de lógica interna y no está destinada a ser heredado por clases fuera de mi montaje; y Derived
es accesible desde el exterior. InternalData
también contiene un poco de lógica interna y, como lo haría (y nunca debería) ser utilizado desde el exterior, también quiero que sea interno.
Por supuesto, el código anterior no se compilará, ya que Base
no debería ser menos accesible que Derived
. Puedo configurar el Base
para que sea public
, eso está bien, pero lleva a otro problema. Si Base
es público, entonces podría haber alguno ExternalDerived : Base
en otro ensamblaje. Pero Base.DoProcess
acepta un argumento InternalData
, por lo que ExternalDerived
no puede implementarlo (ya que no conoce el InternalData
). El constructor interno sin parámetros Base
impide la creación de instancias ExternalDerived
, y por lo tanto, nadie implementará ExternalDerived.DoProcess
y no se necesita la exposición pública InternalData
, pero el compilador no lo sabe.
¿Cómo puedo reescribir el código anterior para que haya un método abstracto DoProcess(InternalData)
y para que la clase InternalData
sea interna?
¡Guau, esa es ciertamente una manera sucia en la que nunca pensé! Estoy aceptando su respuesta, ya que parece ser la única que realmente resuelve el problema, aunque voy a mejor sólo vivo con el 'InternalData' hecho público en lugar :) – penartur
@penartur Todavía no explicó lo que le impide simplemente haciendo 'DoProcess' interno. 'DoProcess interno 'aunque no es óptimo, es ciertamente más limpio que este truco. – CodesInChaos
Como ya he dicho, no voy a implementar este truco en mi código, y estoy exponiendo 'InternalData' en su lugar. En cuanto a su pregunta, básicamente la elección es entre 'InternalData interno; DoProcess interno y 'InternalData público; DoProcess protegido; aunque preferiría 'InternalData interno; DoProcess protegido 'si hubiera tal opción, de estos dos preferiré el último. – penartur