Runtime: Metode antarmuka generik tidak dipanggil

Dibuat pada 10 Agu 2018  ·  3Komentar  ·  Sumber: dotnet/runtime

Kode sampel yang diuji pada perilaku .NET 2/3/4 / 4.5 / 4.6.1 & .Net Core 2.1 sama untuk semua, mengapa ini ditangani seperti ini?

Jelas panggilan ke PrintIt<T> membuat tipe yang benar Bar tetapi tidak pernah benar-benar memanggil metode yang benar.

Kode sampel:

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

Keluaran:

Foo!
Foo!
Foo!
Bar!

Output yang Diharapkan:

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

Komentar yang paling membantu

Ketika Anda 'baru' Print (), metode itu bukan bagian dari antarmuka PrintMe.

Anda akan mendapatkan hasil yang sama dengan

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

Tidak ada obat generik sama sekali.

Semua 3 komentar

Ketika Anda 'baru' Print (), metode itu bukan bagian dari antarmuka PrintMe.

Anda akan mendapatkan hasil yang sama dengan

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

Tidak ada obat generik sama sekali.

Ini bukan pertanyaan tentang apa yang dilakukan CLR, ini adalah pertanyaan tentang apa yang dilakukan bahasa tersebut. Spesifikasi C # mengatakan :

Kelas mewarisi semua implementasi antarmuka yang disediakan oleh kelas dasarnya.

Tanpa secara eksplisit mengimplementasikan ulang antarmuka, kelas turunan tidak dapat mengubah pemetaan antarmuka yang diwarisi dari kelas dasarnya.

Spesifikasi kemudian memberikan contoh yang hampir sama dengan yang di atas.

Ini juga berarti bahwa untuk membuatnya berperilaku seperti yang Anda inginkan, Anda perlu mengimplementasikan ulang antarmuka:

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

@svic Terima kasih atas jawabannya

Apakah halaman ini membantu?
0 / 5 - 0 peringkat