Tuesday, August 3, 2010

VB.NET Polymorphism Fail

I have been working on a project where I stumpled upon a classic Polymorphism case which .NET marked as a compile error.

To simplify the problem in order to show it to you , I created the following simple UML design .

The method Add in IBirds is overloaded, it can take a IBird to add it to the Birds list or it also can take IBirds object to add all birds to the list.

Iflyable is also an interface that both Duck and Ducks implement, so when I send I cast Duck or Ducks to IFlyable and send it to Add function it should fit right in without problems

Because IFlyable can be either IBird or IBirds it should definitly work in runtime through late binding. However .NET display this Error instead

Error 1 Overload resolution failed because no accessible 'Add' can be called without a narrowing conversion:
'Public Sub Add(birds As IBirds)': Argument matching parameter 'birds' narrows from 'Birds.IFlyable' to 'Birds.IBirds'.
'Public Sub Add(aBird As IBird)': Argument matching parameter 'aBird' narrows from 'Birds.IFlyable' to 'Birds.IBird'. C:\Documents and Settings\ncs\My Documents\Visual Studio 2008\Projects\Birds\Birds\Form1.vb 26 9 Birds

I think it should be displayed as a warning at least so we can evaluate it on runtime.
The weird thing that it works on Debug mode.

To solve the problem I should put an If statement that check the type of the object and cast it to either IBird or IBirds which I don't like. I wrote an article about how to minimize the number of if statements in your code only to add more?

Here is the Source code for those interested.