Does the following help? import std.algorithm.comparison : castSwitch; import std.stdio;
class A { } class B : A { } class C : A { } auto foo_impl(B b) { writeln("called foo(B)"); } auto foo_impl(C c) { writeln("called foo(C)"); } auto foo(A a) { return a.castSwitch!( (B b) => foo_impl(b), (C c) => foo_impl(c), ); } void main() { B b = new B(); A a = b; foo(a); // called foo(B) } With a bit of template magic, you can make it DRY, e.g. alias foo = buildSwitch!foo_impl;