Is method overloading polymorphism Early Bound in C#?

In C#, if I have

public class BaseClass
{
    //BaseClass implementation
}

public class Derived : BaseClass
{
    //Derived implementation
}

public class AnotherClass
{
    AnotherClass(BaseClass baseClass)
    {
        //Some code
    }

    AnotherClass(Derived derived) : this(derived as BaseClass)
    {
        //Some more code
    }
}

and then do:

BaseClass    baseVariable    = new Derived();
AnotherClass anotherVariable = new AnotherClass(baseVariable);

This will lead to early binding, calling the AnotherClass(BaseClass) method.

Instead, if I cast it using dynamic keyword - or instantiate a variable with dynamic and then pass it as constructor argument, the AnotherClass(Derived) will be invoked:

BaseClass    baseVariable    = new Derived();
//This will instantiate it using the AnotherClass(Derived)
AnotherClass anotherVariable = new AnotherClass(baseVariable as dynamic);

Is method overloading early bound (Evaluated at compile time) in C#? That meaning, is there any other way or trick to determine the mostly-derived call to the other class constructor to apply the invocation of the constructor that takes the mostly derived class type as argument in my case without the use of dynamic or reflection?

Jon Skeet
people
quotationmark

The binding time in C# depends on whether the binding involves dynamic or not. As you've seen, if you use dynamic you get execution-time overload resolution; if you don't, you get compile-time overload resolution.

Note that even when overload resolution involves dynamic typing, it will still use the information known at compile-time - only the expressions which are of type dynamic use the execution-time type. Example of that:

using System;

class Test
{
    static void Main()
    {
        object x = "abc";
        dynamic y = 10;

        Foo(x, y); // Prints Foo(object,int)
    }

    static void Foo(object x, int y)
    {
        Console.WriteLine("Foo(object,int)");
    }

    static void Foo(string x, int y)
    {
        Console.WriteLine("Foo(string,int)");
    }
}

If you change the declared type of x to dynamic, then the execution-time type will be relevant (and it will print Foo(string,int)).

Of course, this is only overload resolution - overriding is always determined at execution time, unless you're using a non-virtual invocation (either invoking a non-virtual method, or using base.Foo(...).

people

See more on this question at Stackoverflow