Что, если я не прислушаюсь к предупреждению «скрывает унаследованный элемент. Чтобы текущий элемент переопределял эту реализацию ….»

#c# #warnings #virtual-functions

#c# #предупреждения #виртуальные функции

Вопрос:

Возможно, это тонкий момент, но он касается предупреждения, которое выдает компилятор, если вы делаете что-то вроде:

 class A
{
    public virtual void F() { }
}
class B : A
{
    public void F() { }
}
  

Затем вы получите предупреждение:

'EomApp1.B.F()' hides inherited member 'EomApp1.A.F()'.
To make the current member override that implementation, add the override keyword. Otherwise use the new keyword.

изображение сообщения об ошибке

ВОПРОС: Какое предупреждение, на самом деле предупреждающее меня, произойдет, если я ничего с этим не сделаю? Будет ли моя программа функционировать по-другому, если я добавлю ключевое слово ‘new’ или если я этого не сделаю?

(Примечание: Я знаю, что мог бы протестировать это достаточно легко, но я подумал, что стоит спросить здесь)

Ответ №1:

Это ничего не сделает, но используемый вами метод F () также не является полиморфным. Становится очень легко допустить ошибку в коде, если вы начали использовать ссылку на базовый класс, следовательно, вы предупреждены. Конечно, это может быть то, что вы хотите, следовательно, ключевое слово new просто делает его более явным

Например.

 B b1 = new B();
b1.F(); // will call B.F()

A b2 = new B();
b2.F(); // will call A.F()
  

Теперь, если вы добавите класс C с new помощью, он будет вести себя так же, как B . Если вы добавляете класс D с override помощью, то F становится полиморфным:

 class C : A
{
    public new void F() { }
}

class D : A
{
    public override void F() { }
}

// Later

C c1 = new C();
c1.F(); // will call C.F()

A c2 = new C();
c2.F(); // will call A.F()

D d1 = new D();
d1.F(); // will call D.F()

A d2 = new D();
d2.F(); // will call D.F()
  

Посмотрите на эту скрипку.

Комментарии:

1. Попробуйте это на VS, но я полагаю, что это вызовет A.F ()

Ответ №2:

Нет, поведение по умолчанию точно такое же, как если бы вы использовали new , за исключением того, выдается ли предупреждение. По моему опыту, вы чаще на самом деле хотите указать override вместо new , поскольку обычно это просто случай, когда забывают явно переопределить.

Если вы действительно хотите совершенно отдельный метод, и если у вас есть возможность использовать вместо этого другое имя, я бы выбрал этот подход. Наличие одного метода, скрывающего другой, обычно значительно снижает читаемость IMO. Это не слишком плохо, если цель состоит в том, чтобы просто указать более конкретный возвращаемый тип (и вы убедитесь, что более слабо типизированный метод возвращает то же значение), но это довольно редкий случай.

Ответ №3:

Это просто предупреждение. Код будет работать. При некоторых обстоятельствах это предупреждение может привести к некоторой проблеме.

используйте ключевое слово new с методом, который вы вызываете из базового класса.

 class A
{
    public virtual void F() { }
}
class B : A
{
   new public void F() { }
}
  

Ссылка

https://msdn.microsoft.com/en-us/library/435f1dw2.aspx

https://msdn.microsoft.com/en-us/library/aa691135 (v = vs.71).aspx