Tim Gittos

I'm an Australian currently living in Austin, TX in the USA.

I currently earn a living programming, though I wouldn't call myself a programmer. If I had to attach a label to myself, I'd use the term autodidact.

I love learning, and my favorite things to learn about are programming, computer graphics, AI & machine learning, robotics, painting and creativity.

C# Interface Method Gotcha When Inheriting

Last updated on 02 Feb 2009

I noticed some interesting behavior from C# yesterday at work. Truth be told, I’ve noticed this in the past, but I’ve only figured out what’s causing it today.

The behavior is this: when you inherit from a class that implements an interface, calling a hidden/overriden method from an object of the inheriting class that has been upcast to the interface will result in a call the the inherited function.

Ok, so that probably made no sense at all, which is why I will explain it, but not before a warning. I’m not sure if this is intended behavior, and I’m not sure if this is something I’m doing wrong. If someone can point me in the direction of an explanation or a correction, I would be very grateful.

On to the explanation.

Take a sample, trivial application that has widgets. These widgets just print messages out to the console. We have an interface, IWidget, which forms the contract for all widgets:

interface IWidget
{
    void DoSomething();
    void DoSomethingElse();
}

Next, we have a generic widget class, which we use for most widgets. This is called GenericWidget:

class GenericWidget : IWidget
{
    public void DoSomething()
    {
        Console.WriteLine("Doing something in GenericWidget");
    }

    public void DoSomethingElse()
    {
        Console.WriteLine("Doing something else in GenericWidget");
    }
}

And finally, we have a specific type of widget that does something different, called SpecificWidget:

class SpecificWidget : GenericWidget
{
    public new void  DoSomething()
    {
        Console.WriteLine("Doing something in SpecificWidget");
    }
    public new void DoSomethingElse()
    {
    Console.WriteLine("Doing something else in SpecificWidget");
    }
}

Now, we want to run some tests on our widgets, to see what’s going on. First, we’ll test the widgets themselves. Running:

GenericWidget genericWidget = new GenericWidget();
genericWidget.DoSomething();
genericWidget.DoSomethingElse();

SpecificWidget specificWidget = new SpecificWidget();
specificWidget.DoSomething();
specificWidget.DoSomethingElse();

will output:

Doing something in GenericWidget
Doing something else in GenericWidget

Doing something in SpecificWidget
Doing something else in SpecificWidget 


 Which is exactly what we expected to see. Test has passed.

Next, lets say we have a function that we want to pass widgets to, but we don’t know what kind of widgets we will be passing, only that they are widgets. So we pass them as widgets, but upcast them to IWidget, and call the methods on them from the interface. For example:

IWidget genericUpcast = new GenericWidget();
genericUpcast.DoSomething();
genericUpcast.DoSomethingElse();
<span class="n">IWidget</span> <span class="n">genericUpcast</span> <span class="p">=</span> <span class="k">new</span> <span class="n">GenericWidget</span><span class="p">();</span>
<span class="n">genericUpcast</span><span class="p">.</span><span class="n">DoSomething</span><span class="p">();</span>
<span class="n">genericUpcast</span><span class="p">.</span><span class="n">DoSomethingElse</span><span class="p">();</span>

IWidget specificUpcast = new SpecificWidget();
specificUpcast.DoSomething();
specificUpcast.DoSomethingElse();


which will give the following output:
Doing something in GenericWidget
Doing something else in GenericWidget

Doing something in GenericWidget
Doing something else in GenericWidget


Wait, that’s not right. The specificUpcast should call the method on SpecificWidget, shouldn’t it? At least, that’s my expected behavior. Just to prove there’s not something wrong with our specificUpcast:
(specificUpcast as SpecificWidget).DoSomething();
(specificUpcast as SpecificWidget).DoSomethingElse();

will yield:
Doing something in SpecificWidget
Doing something else in SpecificWidget 

which is our expected output all along.

If someone can explain this to me, or point me to a better method to upcast, then please do so. I’m finding a lot of my code needs to check for specific types in order to call the proper method, and it seems clunky and awkward. I’m sure I’m doing something wrong, I’m just not sure what.

As usual, you can find the source code here: Interface Upcasting Inherited Classes Gotcha