В C# new
модификатор может использоваться для сокрытия метода базового класса, не переопределяя метод базового класса.
Я никогда не встречался с ситуацией, где сокрытие метода было лучшим доступным выбором. Есть ли какие-либо ситуации, где сокрытие метода является лучшим выбором?
Есть редкие, но очень веские причины использовать скрытие метода. Эрик Липперт опубликовал отличный пример в своем блоге:
interface IEnumerable<T> : IEnumerable {
new IEnumerator<T> GetEnumerator();
}
Однако я думаю, что сокрытие должно быть исключением, и его нужно использовать с осторожностью.
Часто это хороший выбор, когда вы создаете пользовательские элементы управления и хотите предотвратить отображение определенных свойств в дизайнере. Иногда свойства нельзя переопределить, но дизайнера это не волнует, его волнует только то, имеет ли общедоступное свойство нижнего уровня атрибут [Browsable]
.
Например, предположим, что ваш элемент управления не поддерживает заполнение. Свойство Control.Padding переопределить нельзя.Но вы также знаете, что ничего плохого не произойдет, если кто-то установит отступы, просто свойство ничего не делает , поэтому вы не хотите, чтобы ваши пользователи видели это в дизайнере и думаю, что это действительно работает. Итак, скройте его:
public class MyControl : Control
{
[Browsable(false)]
public new Padding Padding
{
get { return base.Padding; }
set { base.Padding = value; }
}
}
В этом случае мы буквально используем скрытие элемента, чтобы скрыть элемент - от дизайнера.
Кстати, я знаю, что есть и другие способы достижения этой цели - это всего лишь один из возможных вариантов.
Да, если вы, например, просто потребитель базового класса и публикуете новую версию базового класса, которая внезапно имеет метод с той же сигнатурой, что и один из уже реализованных вами методов. в производном классе вам нужно иметь возможность скрыть метод базового класса, и вы используете new
, чтобы прояснить, что вы скрываете метод базового класса ...
Самый распространенный пример, который я могу придумать, - это такие вещи, как DbCommand
vs SqlCommand
; конкретные типы ( SqlCommand
и т. д.) обычно скрывают множество методов, чтобы возвращаемые типы свойств / методов отображали правильный тип реализации. Это связано с тем, что сами связанные объекты имеют дополнительные (зависящие от реализации) функции, и вызывающий не хочет выполнять приведение каждый раз, когда они вызывают что-либо.
Иногда я использую его для удобства вызывающих, например:
abstract public class Animal { }
public class Mouse : Animal { }
public class AnimalTrap
{
public Animal TrappedAnimal { get; }
}
public class MouseTrap : AnimalTrap
{
new public Mouse TrappedAnimal
{
get { return (Mouse)base.TrappedAnimal; }
}
}
Таким образом, вызывающему не нужно приводить сами Mouse
, когда производный класс гарантирует, что пойманное животное всегда будет мышь. При этом полиморфная функциональность остается неизменной.