Протестированный образец кода для .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!
Это не вопрос того, что делает CLR, это вопрос того, что делает язык. В спецификации C # сказано :
Класс наследует все реализации интерфейса, предоставляемые его базовыми классами.
Без явной повторной реализации интерфейса производный класс никоим образом не может изменить сопоставления интерфейсов, которые он наследует от своих базовых классов.
Затем в спецификации приводится пример, почти идентичный приведенному выше.
Это также означает, что для того, чтобы заставить его вести себя так, как вы хотите, вам необходимо повторно реализовать интерфейс:
c#
class Bar : Foo, PrintMe
{
public new void Print()
{
Console.WriteLine("Bar!");
}
}
@svick Спасибо за ответ
Самый полезный комментарий
Когда вы « создаете
Вы получите тот же результат с
Никаких дженериков.