In C#, the compiler will pick the right method depending on the declared type of the variable, not on the actual type stored in it.
Note, the code below declares W
to be a class, and constructs an instance of it. If you make W
an interface, and remove its declaration and construction, you'll get the same behavior for x
and y
as the program below, interface or class for W
in this case does not matter.
Let me show you the difference:
using System;
namespace SO2851194
{
class W { }
class X : W { }
class Y : W { }
class Program
{
static void Main()
{
W w = new W();
X x = new X();
Y y = new Y();
doSomething(w);
doSomething(x);
doSomething(y);
}
static void doSomething(W w)
{
Console.Out.WriteLine("w");
}
static void doSomething(X x)
{
Console.Out.WriteLine("x");
}
}
}
Here I declare three variables, of type W
, X
, and Y
, and call doSomething
passing the three variables, one by one. The output of this program is:
w
x
w
As expected, the compiler will pick the method that has the best fitting parameter type, and in the case of the x
variable, it has a method that can take an object of type X
.
However, due to class inheritance, we can change the declaration of the variables, but keep the object types constructed, so changing the code like this:
W w = new W();
W x = new X(); // Notice, changed variable type to W
W y = new Y(); // but keep constructing X and Y
This now outputs:
w
w
w
So the fact that the x
variable contained an object of type X
didn't factor into it, the compiler picked the method from the variable type, not its contents.
In C# 4.0, you now have the dynamic
type, so again changing the code to:
dynamic w = new W();
dynamic x = new X();
dynamic y = new Y();
again outputs:
w
x
w
as now the compiler defers picking any method at all until runtime, and at runtime, it sees that the variable named x
actually contains an object of type X
and then picks the method with the best fitting parameter type.