.net does not allow the implementation of a partial interface in base classes. As a mitigation, I came up with 3 alternative solutions. Please help me decide which is more universal in terms of refactoring, compilation errors / runtime, readability. But first a few comments.
- Of course, you can always use an object for IFoo and call any method without warning the compiler. But this is not logical, you would not do it normally. This construct will not result from refactoring.
- I want maximum separation. The direct class contract (public methods and properties) must be separated by the implementation of the interface. I use interfaces to separate the interaction of objects.
My comparison:
- BaseClass1 / MyClass1:
- con: you need to create a virtual abstract in BaseClass1 for every non-implemented IFoo method.
- con: An additional method transfer is a minor performance impact at runtime.
- BaseClass2 / MyClass2:
- con: no compiler warning if Method2 function is not implemented in MyClass2. Runtime exception. Poor refactoring unit test can potentially destabilize code.
- con: should add an additional obsolete construct to prevent direct method invocation from child classes.
- con: Method2 is publicly available for BaseClass1, so now it is part of the class contract. Must put an "Deprecated" construct to prevent a direct call, not via IFoo.
- BaseClass3 / MyClass3:
- pro: ( № 2). . , MyClass2.Method2 - IFoo, overriden.
public interface IFoo
{
void Method1();
void Method2();
}
public abstract class BaseClass1 : IFoo
{
void IFoo.Method1()
{
}
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()
{
}
}
public abstract class BaseClass2 : IFoo
{
void IFoo.Method1()
{
}
[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()
{
}
}
public abstract class BaseClass3 : IFoo
{
void IFoo.Method1()
{
}
void IFoo.Method2()
{
throw new NotSupportedException();
}
}
public abstract class MyClass3 : BaseClass3, IFoo
{
void IFoo.Method2()
{
}
}