Tested sample code on .NET 2/3/4/4.5/4.6.1 & .Net Core 2.1 behavior is the same for all, why is this handled like this?
Clearly the call to PrintIt<T>
is creating the correct type Bar
but never actually calls the correct method.
interface PrintMe
{
void Print();
}
class Foo : PrintMe
{
public void Print()
{
Console.WriteLine("Foo!");
}
}
class Bar : Foo
{
public new void Print()
{
Console.WriteLine("Bar!");
}
}
class Program
{
static void Main(string[] args)
{
PrintIt<Foo>();
PrintIt<Bar>();
var foo = new Foo();
var bar = new Bar();
foo.Print();
bar.Print();
Console.ReadKey();
}
static void PrintIt<T>() where T : PrintMe, new()
{
new T().Print();
}
}
Foo!
Foo!
Foo!
Bar!
Foo!
Bar!
Foo!
Bar!
When you 'new' Print(), that method isn't part of the PrintMe interface.
You'll get the same result with
((PrintMe)new Bar()).Print();
No generics at all.
This is not a question of what the CLR does, it's a question of what the language does. The C# specification says:
A class inherits all interface implementations provided by its base classes.
Without explicitly re-implementing an interface, a derived class cannot in any way alter the interface mappings it inherits from its base classes.
The spec then provides an example that's almost identical to the one above.
This also means that to make it behave the way you want, you need to re-implement the interface:
c#
class Bar : Foo, PrintMe
{
public new void Print()
{
Console.WriteLine("Bar!");
}
}
@svick Thanks for the answer
Most helpful comment
When you 'new' Print(), that method isn't part of the PrintMe interface.
You'll get the same result with
No generics at all.