El código de muestra probado en .NET 2/3/4 / 4.5 / 4.6.1 y el comportamiento de .Net Core 2.1 es el mismo para todos, ¿por qué se maneja así?
Claramente, la llamada a PrintIt<T>
está creando el tipo correcto Bar
pero nunca llama al método correcto.
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!
Cuando imprime 'nuevo' (), ese método no es parte de la interfaz PrintMe.
Obtendrá el mismo resultado con
((PrintMe)new Bar()).Print();
Nada de genéricos.
Esta no es una cuestión de lo que hace el CLR, es una cuestión de lo que hace el lenguaje. La especificación de C # dice :
Una clase hereda todas las implementaciones de interfaz proporcionadas por sus clases base.
Sin volver a implementar explícitamente una interfaz, una clase derivada no puede alterar de ninguna manera las asignaciones de interfaz que hereda de sus clases base.
Luego, la especificación proporciona un ejemplo que es casi idéntico al anterior.
Esto también significa que para que se comporte de la manera deseada, debe volver a implementar la interfaz:
c#
class Bar : Foo, PrintMe
{
public new void Print()
{
Console.WriteLine("Bar!");
}
}
@svick Gracias por la respuesta
Comentario más útil
Cuando imprime 'nuevo' (), ese método no es parte de la interfaz PrintMe.
Obtendrá el mismo resultado con
Nada de genéricos.