Two classes, D1
and D2
derive from an abstract base class B
. Each of them share common public interface declared in B
but each of them might also have their own specific public interface (e.g. D2
has D2.Bar()
which makes sense only for D2
objects):
public abstract class B
{
public int N { get; set; }
public abstract void Foo();
}
public class D1 : B
{
public override void Foo()
{
}
}
public class D2 : B
{
public override void Foo()
{
}
public void Bar()
{
}
}
I keep mix of derived objects in a single collection, (e.g. list) as sometimes I have to call common (inherited) methods on all objects from the collection but sometimes I want to call Bar()
on D2
objects only:
var list = new List<B>();
list.Add(new D1());
list.Add(new D2());
foreach(var b in list)
if(b is D2)
(b as D2).Bar();
I feel the code smell here. Downcasting is a bad idea, making decisions based on type checks is bad idea. If I move Bar()
to base class, it will not make sense calling it on D1
objects (what would implementation of D1.Bar()
contain?). Interface and composition don't help either. I feel this is a very common situation and am wondering what's the best practice in this case? How to avoid downcasting but allow calling public methods specific for derived types?