.net no permite la implementación parcial de la interfaz en las clases base. Como mitigación, he llegado a 3 soluciones alternativas. Ayúdeme a decidir cuál es más universal en términos de refactorización, compilación/errores de tiempo de ejecución, legibilidad. Pero primero un par de comentarios.Implementación de la mejor interfaz parcial C# en la clase básica/abstracta
- Por supuesto, siempre puede lanzar el objeto a IFoo y llamar a cualquier método sin ninguna advertencia del compilador. Pero no es lógico, no harías eso normalmente. Esta construcción no ocurriría como resultado de la refactorización.
- Quiero la máxima separación. El contrato de clase directo (métodos y propiedades públicas) debe separarse con implementaciones de interfaz. Utilizo las interfaces mucho para separar las interacciones entre objetos.
Mi comparación:
- BaseClass1/MyClass1:
- con: tiene que crear abstracta virtual en BaseClass1 para cada método no se han aplicado de IFoo.
- con: Envoltura de método adicional: leve impacto de productividad en el tiempo de ejecución.
- BaseClass2/miclase2:
- con: ninguna advertencia del compilador si no hay aplicación del Método 2 en miclase2. Excepción de tiempo de ejecución en su lugar. La refacturación con una cobertura de prueba pobre de la unidad puede desestabilizar el código.
- con: tiene que poner una construcción obsoleta adicional para evitar la llamada al método directo de las clases secundarias.
- con: Method2 es público para BaseClass1, por lo que ahora forma parte del contrato de clase. Tengo que poner la construcción "Obsoleta" para evitar la llamada directa, no a través de IFoo.
- BaseClass3/MyClass3:
- Pro: (En comparación con # 2). Más legible Verás que MyClass2.Method2 es una implementación IFoo, no solo un método anulado.
public interface IFoo
{
void Method1();
void Method2();
}
public abstract class BaseClass1 : IFoo
{
void IFoo.Method1()
{
//some implementation
}
void IFoo.Method2()
{
IFooMethod2();
}
protected abstract void IFooMethod2();
}
public class MyClass1 : BaseClass1
{
[Obsolete("Prohibited direct call from child classes. only inteface implementation")]
protected override void IFooMethod2()
{
//some implementation
}
}
public abstract class BaseClass2 : IFoo
{
void IFoo.Method1()
{
//some implementation
}
[Obsolete("Prohibited direct call from child classes. only inteface implementation")]
public virtual void Method2()
{
throw new NotSupportedException();
}
}
public abstract class MyClass2 : BaseClass2
{
public override void Method2()
{
//some implementation
}
}
public abstract class BaseClass3 : IFoo
{
void IFoo.Method1()
{
//some implementation
}
void IFoo.Method2()
{
throw new NotSupportedException();
}
}
public abstract class MyClass3 : BaseClass3, IFoo
{
void IFoo.Method2()
{
//some implementation
}
}
Este es un patrón ** muy ** incómodo que intentas implementar. Usted dijo * ". NET no permite la implementación parcial de la interfaz en las clases base." * - hay una razón para eso. El código de cliente espera algo que ** implemente una interfaz ** para, ya sabes, quizás ... ** implementar la interfaz **. Lanzar excepciones para los métodos no compatibles como una cuestión de rutina es * muy * malo código olor ... – Yuck
De acuerdo con Yuck. Si tiene una variable de tipo 'IFoo', realmente espera que todos los métodos de' IFoo' estén implementados y disponibles. Las interfaces están hechas para eso. – ken2k
Solo MyClass1 _must_ implementa completamente la interfaz. Y lo hace. El problema es que hay varias clases secundarias (no las mencioné antes), cada una debe implementar IFoo. Sin la clase base, debe copiar/pegar la implementación de Method1, que es igual para todas las clases secundarias.Esto es lo que trato de evitar Pero la implementación de Method2 es diferente en clases secundarias, por lo que no puedo tener solo una clase que implemente tanto Method1 como Method2. – user1194528