import std.stdio; char[] itoa(uint i) { if (i < 10) { return ""~cast(char)(i + 48); } else { uint i2 = i / 10; return itoa(i2)~cast(char)(i - i2*10 + 48); } } char[] trycast(int max) { char[] result = ""; for (uint i = 0; i < max; i++) result ~= "if (cast(T["~itoa(i)~"])x !is null) { dg["~itoa(i)~"](); return; }"; return result; } template check(T...) { void check(Tx)(Tx x, void delegate()[] dg ...) { static if (is(Tx == T[0])) { // writefln("exact match"); dg[0](); } else { mixin(trycast(T.length)); throw new Exception("cast error"); } } } class TypeA0 { int id = 10; } class TypeA : TypeA0 { int id = 11; } class TypeA2 : TypeA { int id = 12; } class TypeB { int id = 20; } void main() { auto x = new TypeA; check!(TypeA, TypeB)(x, {writefln("TypeA id=%s", x.id);}, {writefln("TypeB id=%s", x.id);}); }