I was surprised when I ran into this situation and realized I wasn’t sure what the best solution was.
Say I have the following three types:
class A { }
class B : A { }
class C : A { }
And the following three methods:
DoSomething(A a){ }
DoSomething(B b){ }
DoSomething(C c){ }
I have a List<A> which contains objects of type B and C
I would like to do this:
foreach(A a in list) { DoSomething(a) }
and have it call the method which matches most closely to the underlying type,
but of course this will always call DoSomething(A a)
I’d prefer not to have a bunch of type checking to get the right method call, and I don’t want to add anything to the classes A, B or , C.
Is it possible?
This is a rather well-known issue with virtual dispatch in statically typed languages: it only handles one parameter (
this) “virtually”; for all other parameters, the method call is bound using the static type of the argument. Since your list is a list ofA, the code is only ever going to call theAoverload.You would need multiple dispatch to achieve the stated goal, and since the language does not provide this out of the box unless you switch to
dynamic, so you will have to either make the switch or implement it yourself. There are many tradeoffs to consider when making this decision (and also when deciding how to implement multiple dispatch if needed), so don’t do this lightly.