Когда использовать новый вместо переопределения С#
Возможный дубликат:
Использование ключевого слова С# virtual + override vs. new
Разница между новыми и отменой?
Итак, я работал над проектом и решил немного прочитать о различиях между ключевыми словами new
и override
на С#.
Из того, что я видел, кажется, что использование функциональности ключевых слов new
- отличный способ создать ошибки в коде. Кроме того, я действительно не вижу, когда на самом деле имеет смысл использовать его.
Больше из любопытства, чем что-либо, есть ли какой-либо шаблон, где ключевое слово new
- правильный путь?
Ответы
Ответ 1
Ключевое слово new
- это правильный путь, когда вы хотите скрыть базовую реализацию, и вам все равно, что вы не сможете вызвать свой метод при обработке вашего объекта полиморфно.
Позвольте мне пояснить. Рассмотрим следующее:
public class Base
{
public void DoSomething()
{
Console.WriteLine("Base");
}
}
public class Child : Base
{
public void new DoSomething()
{
Console.WriteLine("Child");
}
}
Время от времени полезно скрывать функциональность базового класса у ребенка, следовательно, использовать ключевое слово new
. Проблема в том, что некоторые разработчики делают это слепо, что приведет к следующему побочному эффекту (отсюда и "ошибки", которые вы упомянули):
Base instance = new Child();
instance.DoSomething(); // may expect "Child" but writes "Base"
Ответ 2
Одна вещь new
дает вам возможность сделать так, как будто вы можете переопределить метод, который не объявлен виртуальным. Имейте в виду, что вы не переопределяете, но на самом деле объявляете метод с тем же именем.
Чтобы использовать override
, метод должен быть помечен как virtual
или abstract
.
public class PolyTest
{
public void SomeMethod()
{
Console.WriteLine("Hello from base");
}
}
public class PolyTestChild : PolyTest
{
new public void SomeMethod()
{
Console.WriteLine("Hello from child");
}
}
Что касается вашего комментария о багги-коде, если базовая реализация выполняет то, что вы или вызывающий абонент ожидает, вот где ошибка. Однако я не вижу это более опасным, чем не вызов base.SomeMethod
(при переопределении), и вам нужно.
Ответ 3
new
имеет свое место, и это считается отличным способом для правильного кода ошибки, если вы не знаете, как его использовать.
Один пример:
public class A
{
public void AMethod() { }
}
public class B : A
{
public override void AMethod() { }
}
В этой ситуации AMethod
нельзя переопределить с помощью B
, потому что это не virtual
или abstract
, поэтому для обеспечения пользовательской реализации вы должны использовать new
.