Runtime: No se llama al método de interfaz genérico

Creado en 10 ago. 2018  ·  3Comentarios  ·  Fuente: dotnet/runtime

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.

Código de muestra:

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();
    }
}

Salida:

Foo!
Foo!
Foo!
Bar!

Rendimiento esperado:

Foo!
Bar!
Foo!
Bar!
question tracking-external-issue

Comentario más útil

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.

Todos 3 comentarios

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

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

matty-hall picture matty-hall  ·  3Comentarios

sahithreddyk picture sahithreddyk  ·  3Comentarios

noahfalk picture noahfalk  ·  3Comentarios

jamesqo picture jamesqo  ·  3Comentarios

jzabroski picture jzabroski  ·  3Comentarios