Runtime: Méthode d'interface générique non appelée

Créé le 10 août 2018  ·  3Commentaires  ·  Source: dotnet/runtime

L'exemple de code testé sur .NET 2/3/4 / 4.5 / 4.6.1 et .Net Core 2.1 est le même pour tous, pourquoi est-ce géré comme ceci?

Il est clair que l'appel à PrintIt<T> crée le type correct Bar mais n'appelle jamais la bonne méthode.

Exemple de code:

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

Production:

Foo!
Foo!
Foo!
Bar!

Production attendue:

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

Commentaire le plus utile

Lorsque vous «nouveau» Print (), cette méthode ne fait pas partie de l'interface PrintMe.

Vous obtiendrez le même résultat avec

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

Pas de génériques du tout.

Tous les 3 commentaires

Lorsque vous «nouveau» Print (), cette méthode ne fait pas partie de l'interface PrintMe.

Vous obtiendrez le même résultat avec

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

Pas de génériques du tout.

Ce n'est pas une question de ce que fait le CLR, c'est une question de ce que fait la langue. La spécification C # dit :

Une classe hérite de toutes les implémentations d'interface fournies par ses classes de base.

Sans réimplémenter explicitement une interface, une classe dérivée ne peut en aucune manière modifier les applications d'interface hérite de ses classes de base.

La spécification fournit ensuite un exemple presque identique à celui ci-dessus.

Cela signifie également que pour le faire se comporter comme vous le souhaitez, vous devez réimplémenter l'interface:

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

@svick Merci pour la réponse

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

GitAntoinee picture GitAntoinee  ·  3Commentaires

chunseoklee picture chunseoklee  ·  3Commentaires

aggieben picture aggieben  ·  3Commentaires

ilmax picture ilmax  ·  3Commentaires

noahfalk picture noahfalk  ·  3Commentaires