I crashed Mads' C# Tech Chat at Tech Ed EMEA in Barcelona on the grounds that the dynamic world has monkey-patched C#.  It was fun, and I had the opportunity to answer a few dynamic/DLR-related questions that Mads was probably more capable of handling than I was.

One question that I choked on was whether or not this new language feature could be used to enable multiple dispatch from within C#.  My gut feeling was that the answer was “yes”, but I couldn’t quite justify the answer so I hedged and hemmed and hawed and didn’t provide anything remotely like a satisfactory answer for the guy asking the question.

But now that I’ve had the benefit of a good night’s rest, the answer is blindingly obvious: yes, and here’s the evidence in some C# 4 sample code:

public class A {
}
 
public class B : A {
}
 
public class C : B {
}
 
public class D {
}
 
public class E : D {
}
 
public class Test {
    public void Multi(D d, A a) { System.Console.WriteLine("DA"); }
    public void Multi(D d, B b) { System.Console.WriteLine("DB"); }
    public void Multi(D d, C c) { System.Console.WriteLine("DC"); }
    public void Multi(E e, A a) { System.Console.WriteLine("EA"); }
    public void Multi(E e, B b) { System.Console.WriteLine("EB"); }
    public void Multi(E e, C c) { System.Console.WriteLine("EC"); }
 
    public static void Main() {
        Test test = new Test();
        A a = new A();
        A b = new B();
        A c = new C();
        D d = new D();
        D e = new E();
        test.Multi(d, a);
        test.Multi(e, b);
        test.Multi(e, c);
        test.Multi((dynamic)d, (dynamic)a);
        test.Multi((dynamic)e, (dynamic)b);
        test.Multi((dynamic)e, (dynamic)c);
    }
}

This produces the output

DA
DA
DA
DA
EB
EC

Why does it work?

When you use dynamic, you’re telling the C# binder to ignore anything that it knows about the type at compile time and to instead determine dispatch based on the actual type at runtime.  The statically-bound method calls, by contrast, performs a dispatch based solely on the declared type.

So there you have it – one more use for dynamic: painless implementation of multiple dispatch.

(Thanks to Lucian Wischik for pointing out a flaw with the original version of this post.)