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?
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(...)
.
See more on this question at Stackoverflow