Модификатор new (справочник по C#)

При использовании в качестве модификатора объявления ключевое слово new явным образом скрывает члены, унаследованные от базового класса. При скрытии унаследованного члена его производная версия заменяет версию базового класса. Предполагается, что версия базового класса элемента является видимой, так как она уже была бы скрыта, если бы была помечена как private или в некоторых случаях как internal. Хотя элементы public или protected можно скрывать без использования модификатора new, в этом случае выводится предупреждение компилятора. При использовании new для явного скрытия члена, предупреждение не появляется.

Ключевое слово new можно также использовать для создания экземпляра типа или как ограничение универсального типа.

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

public class BaseC
{
    public int x;
    public void Invoke() { }
}
public class DerivedC : BaseC
{
    new public void Invoke() { }
}

В этом примере BaseC.Invoke скрывается с помощью DerivedC.Invoke. Поле x не затрагивается, поскольку оно не скрыто таким же именем.

Скрытие имен через наследование принимает одну из следующих форм.

  • Как правило, константы, поля, свойства и типы, которые вводятся в классе или структуре, скрывают все члены базового класса с таким же именем. Однако существуют особые случаи. Например, если объявить новое поле с именем N, чтобы сделать тип невызываемым, в то время как в базовом типе был объявлен метод N, новое поле не скрывает базовое объявление в синтаксисе вызова. Дополнительные сведения см. в разделе Поиск членов в спецификации языка C#.

  • Метод, введенный в классе или структуре, скрывает свойства, поля и типы с тем же именем в базовом классе. Кроме того, он также скрывает все методы базового класса, имеющие такую же сигнатуру.

  • Индексатор, представленный в классе или структуре, скрывает все индексаторы базового класса, имеющие одинаковую сигнатуру.

Совместное использование модификаторов new и override в одном члене является недопустимым, так как эти два модификатора имеют взаимоисключающие значения. Модификатор new создает новый член с таким же именем и приводит к скрытию исходного члена. Модификатор override расширяет реализацию для наследуемого члена.

При использовании модификатора new в объявлении, которое не скрывает наследуемый член, возникает предупреждение.

Примеры

В этом примере базовый класс BaseC и производный класс DerivedC используют одно и то же имя поля x, которое скрывает значение унаследованного поля. В примере показано использование модификатора new. Здесь также показано обращение к скрытым членам базового класса с помощью их полных имен.

public class BaseC
{
    public static int x = 55;
    public static int y = 22;
}

public class DerivedC : BaseC
{
    // Hide field 'x'.
    new public static int x = 100;

    static void Main()
    {
        // Display the new value of x:
        Console.WriteLine(x);

        // Display the hidden value of x:
        Console.WriteLine(BaseC.x);

        // Display the unhidden member y:
        Console.WriteLine(y);
    }
}
/*
Output:
100
55
22
*/

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

public class BaseC
{
    public class NestedC
    {
        public int x = 200;
        public int y;
    }
}

public class DerivedC : BaseC
{
    // Nested type hiding the base type members.
    new public class NestedC
    {
        public int x = 100;
        public int y;
        public int z;
    }

    static void Main()
    {
        // Creating an object from the overlapping class:
        NestedC c1  = new NestedC();

        // Creating an object from the hidden class:
        BaseC.NestedC c2 = new BaseC.NestedC();

        Console.WriteLine(c1.x);
        Console.WriteLine(c2.x);
    }
}
/*
Output:
100
200
*/

В случае удаления модификатора new программа продолжит компиляцию и выполнение, однако появится следующее предупреждение.

The keyword new is required on 'MyDerivedC.x' because it hides inherited member 'MyBaseC.x'.

Спецификация языка C#

Дополнительные сведения см. в разделе Модификатор new в спецификации языка C#.

См. также