Runtime: Generische Schnittstellenmethode wird nicht aufgerufen

Erstellt am 10. Aug. 2018  ·  3Kommentare  ·  Quelle: dotnet/runtime

Der getestete Beispielcode für .NET 2/3/4 / 4.5 / 4.6.1 und .Net Core 2.1 ist für alle gleich. Warum wird dies so gehandhabt?

Es ist klar, dass der Aufruf von PrintIt<T> den richtigen Typ Bar aber niemals die richtige Methode aufruft.

Beispielcode:

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

Ausgabe:

Foo!
Foo!
Foo!
Bar!

Erwartete Ausgabe:

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

Hilfreichster Kommentar

Wenn Sie ‚neues‘ Print (), ist das Verfahren der PrintMe Schnittstelle nicht Teil.

Sie erhalten das gleiche Ergebnis mit

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

Überhaupt keine Generika.

Alle 3 Kommentare

Wenn Sie ‚neues‘ Print (), ist das Verfahren der PrintMe Schnittstelle nicht Teil.

Sie erhalten das gleiche Ergebnis mit

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

Überhaupt keine Generika.

Dies ist keine Frage dessen, was die CLR tut, sondern eine Frage dessen, was die Sprache tut. Die C # -Spezifikation sagt :

Eine Klasse erbt alle Schnittstellenimplementierungen, die von ihren Basisklassen bereitgestellt werden.

Ohne eine explizite Neuimplementierung einer Schnittstelle kann eine abgeleitete Klasse die Schnittstellenzuordnungen, die sie von ihren Basisklassen erbt, in keiner Weise ändern.

Die Spezifikation liefert dann ein Beispiel, das fast identisch mit dem obigen ist.

Dies bedeutet auch, dass Sie die Schnittstelle erneut implementieren müssen, damit sie sich wie gewünscht verhält:

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

@svick Danke für die Antwort

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen