Обложка канала

.NET Разработчик

Опытный разработчик не так давно зашёл в .Net и поставил цель получить сертификат Microsoft. Свой ежедневный прогресс он описывает на канале .Net Разработчик. Заметки об изученном материале, советы по повышению производительности и поддержке мотивации, ин

.NET Разработчик

4 года назад
Открыть в
День 1209. #ЗаметкиНаПолях Полиморфизм в C#: Override и New В чём разница между созданием виртуального/переопределяемого метода и простым сокрытием метода с помощью ключевого слова new в C#? Во-первых, в отличие от переопределения, при использовании ключевого слова new вы можете изменить тип возвращаемого значения. Однако, это ещё не всё. Допустим, у нас есть родительский класс и два потомка. Один потомок использует override, другой – new:
class Parent
{
  public virtual void WhoAmI() =>
    Console.WriteLine("Parent");
}

class Child : Parent
{
  public override void WhoAmI() =>
    Console.WriteLine("Child");
}

class ChildNew : Parent
{
  public new void WhoAmI() =>
    Console.WriteLine("ChildNew");
}

Тогда что выведет следующий код?
Parent child = new Child();
child.WhoAmI();

Parent childNew = new ChildNew();
childNew.WhoAmI();

На первый взгляд кажется, что в обоих случаях случае он выведет одно и то же. В конце концов, в обоих случаях производный тип приводится к родительскому. При таком кастинге важно учитывать, что объект «всегда помнит, кто он». То есть Child можно привести к Parent или даже к object, и он всё равно помнит, что он Child. Так что же выведет код выше?
Child
Parent

Итак, Child с переопределённым методом запомнил, кто он есть, и, следовательно, был вызван тот же метод WhoAmI(), но переопределённый. В случае с ChildNew… это не совсем так. На самом деле, если подумать, объяснение довольно простое. Когда вы используете ключевое слово override, оно переопределяет базовый класс, и между двумя методами существует своего рода «связь». То есть известно, что дочерний член является переопределением базового. Когда вы используете ключевое слово new, вы говорите, что эти два метода никак не связаны между собой. И что ваш новый метод существует только в дочернем классе, но не в родительском. Между ними нет «связи». Поэтому при приведении к родительскому классу переопределённый метод известен, а «новый» метод — нет. Ключевое слово new полезно в некоторых исключительных случаях, например, для переопределения (скрытия) методов сторонних библиотек. Однако, в своей иерархии наследования его использовать не стоит. Мало того, что для этого очень мало причин, так ещё и нарушается принцип подстановки Лисков. Источник: dotnetcoretutorials.com/2022/05…in-c-net