Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern for calling method which takes the most derived form of the passed object

Tags:

c#

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?

like image 691
Erix Avatar asked Dec 11 '22 20:12

Erix


1 Answers

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 of A, the code is only ever going to call the A overload.

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.

like image 145
Jon Avatar answered Feb 02 '23 09:02

Jon