Runtime: Método de interface genérico não sendo chamado

Criado em 10 ago. 2018  ·  3Comentários  ·  Fonte: dotnet/runtime

O código de amostra testado no comportamento do .NET 2/3/4 / 4.5 / 4.6.1 e .Net Core 2.1 é o mesmo para todos, por que isso é tratado assim?

Claramente, a chamada para PrintIt<T> está criando o tipo correto Bar mas nunca realmente chama o método correto.

Código de amostra:

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

Resultado:

Foo!
Foo!
Foo!
Bar!

Resultado esperado:

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

Comentários muito úteis

Quando você 'novo' Print (), esse método não faz parte da interface do PrintMe.

Você obterá o mesmo resultado com

((PrintMe)new Bar()).Print();

Sem genéricos.

Todos 3 comentários

Quando você 'novo' Print (), esse método não faz parte da interface do PrintMe.

Você obterá o mesmo resultado com

((PrintMe)new Bar()).Print();

Sem genéricos.

Não é uma questão do que o CLR faz, é uma questão do que a linguagem faz. A especificação C # diz :

Uma classe herda todas as implementações de interface fornecidas por suas classes básicas.

Sem explicitamente re-implementação de uma interface, uma classe de derivados não podem de qualquer forma alterar os mapeamentos de interface que herda das classes de base.

A especificação fornece um exemplo quase idêntico ao anterior.

Isso também significa que, para fazer com que ele se comporte da maneira que você deseja, é necessário reimplementar a interface:

c# class Bar : Foo, PrintMe { public new void Print() { Console.WriteLine("Bar!"); } }

@svick Obrigado pela resposta

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

Timovzl picture Timovzl  ·  3Comentários

ilmax picture ilmax  ·  3Comentários

GitAntoinee picture GitAntoinee  ·  3Comentários

jzabroski picture jzabroski  ·  3Comentários

noahfalk picture noahfalk  ·  3Comentários