Compile time polymorphism vs. run time polymorphism

Well, overloading decisions (which method signatures are used, based on the arguments1) are made by the compiler, whereas overriding decisions (which method implementations are used, based on the type of the target of the method) are made by the CLR at execution time.

I wouldn’t usually call overloading “polymorphism” though. In my experience the word usually refers to overriding. I suppose overloading does allow you to treat an object of one type as another, although overloading itself doesn’t need to be involved there – it’s just normal type conversions.

Here’s an example showing that overload choice is performed at compile time:

using System;

class Test
{
    static void Foo(object a)
    {
        Console.WriteLine("Object overload called");
    }

    static void Foo(string a)
    {
        Console.WriteLine("String overload called");
    }

    static void Main()
    {
        object x = "hello";
        Foo(x);
    }
}

Here the Foo(object) overload is called because x is of type object at compile time – it’s only at execution time that it’s known to refer to a string.

Compare that with this example:

using System;

class Base
{
    public virtual void Foo()
    {
        Console.WriteLine("Base.Foo called");
    }
}

class Derived : Base
{
    public override void Foo()
    {
        Console.WriteLine("Derived.Foo called");
    }
}

class Test
{
    static void Main()
    {
        Base x = new Derived();
        x.Foo();
    }
}

Here the compile-time type of x is Base, but it’s still the derived class’s overriding method which is called, because the execution-time type of the object that x refers to is Derived.


1 It’s slightly more complicated than that in fact, due to method hiding etc – but in simple cases you can think of it as just picking the signature.

Leave a Comment