Runtime: Общий метод интерфейса не вызывается

Созданный на 10 авг. 2018  ·  3Комментарии  ·  Источник: dotnet/runtime

Протестированный образец кода для .NET 2/3/4 / 4.5 / 4.6.1 и .Net Core 2.1 одинаков для всех, почему это обрабатывается так?

Очевидно, что вызов PrintIt<T> создает правильный тип Bar но на самом деле никогда не вызывает правильный метод.

Образец кода:

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

Вывод:

Foo!
Foo!
Foo!
Bar!

Ожидаемый результат:

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

Самый полезный комментарий

Когда вы « создаете

Вы получите тот же результат с

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

Никаких дженериков.

Все 3 Комментарий

Когда вы « создаете

Вы получите тот же результат с

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

Никаких дженериков.

Это не вопрос того, что делает CLR, это вопрос того, что делает язык. В спецификации C # сказано :

Класс наследует все реализации интерфейса, предоставляемые его базовыми классами.

Без явной повторной реализации интерфейса производный класс никоим образом не может изменить сопоставления интерфейсов, которые он наследует от своих базовых классов.

Затем в спецификации приводится пример, почти идентичный приведенному выше.

Это также означает, что для того, чтобы заставить его вести себя так, как вы хотите, вам необходимо повторно реализовать интерфейс:

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

@svick Спасибо за ответ

Была ли эта страница полезной?
0 / 5 - 0 рейтинги