Мы с коллегой изучали поведение new
ключевого слова в C #, поскольку оно относится к концепции сокрытия. Из документации :
Используйте новый модификатор, чтобы явно скрыть член, унаследованный от базового класса. Чтобы скрыть унаследованный член, объявите его в производном классе с тем же именем и измените его с помощью нового модификатора.
Мы прочитали документацию, и мы понимаем, что она в основном делает и как это делает. То, что мы не могли понять, почему вы должны сделать это в первую очередь. Модификатор существует с 2003 года, и мы оба работаем с .Net дольше, и он никогда не появится.
Когда это поведение будет необходимо в практическом смысле (например, применительно к бизнес-кейсу)? Является ли эта функция изжившей свою полезность, или она просто достаточно необычна в том, что мы делаем (в частности, мы делаем веб-формы и приложения MVC и некоторые небольшие факторы WinForms и WPF)? Опробовав это ключевое слово и поиграв с ним, мы обнаружили некоторые варианты поведения, которые позволяют ему казаться немного опасными при неправильном использовании.
Это звучит немного открыто, но мы ищем конкретный вариант использования, который можно применить к бизнес-приложению, которое находит этот конкретный инструмент полезным.
Ответы:
Вы можете использовать его для имитации ковариации возвращаемого типа. Объяснение Эрика Липперта . Эрик предоставляет этот пример кода:
Это обходной путь.
public override Fish Contents() { ... }
не является законным, несмотря на свою безопасность.В общем, вы не должны использовать скрытие методов, так как это вводит в заблуждение потребителей вашего класса (конкретный пример выше не страдает от этой проблемы). Просто назовите ваш новый метод как-нибудь еще, если вы не хотите переопределять существующий метод.
Скорее всего, в реальной ситуации вам понадобится скрыть метод, если поставщик базового класса добавит универсальный метод, который вы уже добавили в производный класс. Такая программа скомпилирует (и выдаст предупреждения) без ключевого слова new, но добавление
new
говорит: «Я знаю, что моя версия этого метода заменяет версию базового класса. Это ужасно и запутанно, но мы застряли с этим». Это все же лучше, чем заставлять производный класс переименовывать свой метод.Простое обращение к производному методу как к переопределению может вызвать проблемы. Игнорируя любые проблемы с реализацией компилятора, новый метод семантически отличается от базового метода, но полиморфизм вызовет вызов нового метода при запросе вызова метода с тем же именем.
Эта ситуация подробно обсуждается в этом посте Эриком Липпертом.
источник
new
что был маркером "это ужасно и запутанно".Я думаю, что это есть на тот случай, если вам понадобится сделать что-то, о чем дизайнеры языка могли и не подумать. C # был во многом реакцией на ранние версии Java. И одна вещь, которую сделал java, состояла в том, чтобы очень явно заразить разработчиков, чтобы исключить возможность того, что разработчики застрелились в ноги. C # выбрал немного другой подход и дал разработчикам немного больше возможностей, позволяя разработчикам еще больше возможностей выстрелить себе в ноги. Одним из примеров является
unsafe
ключевое слово. Этоnew
ключевое слово другое.Теперь это, вероятно, не так полезно,
unsafe
но, как только вы попадаете в языковую спецификацию, трудно выйти из языковой спецификации.источник
Он говорит читателю, что «я намеренно скрыл реализацию этого метода в базовом классе», а не случайно.
источник
Возможно, вы захотите, чтобы предыдущий участник был доступен через другое имя:
Приветствия.
источник
Я нашел это весьма полезным при создании набора тестов для устаревшего кода. Это позволяет мне скрывать внешние зависимости, например, запрашивать базу данных внутри метода, который используется другими методами. Чтобы иметь возможность тестировать другие методы, я могу скрыть оригинальную логику, которая зависит от внешних ресурсов, без необходимости добавлять виртуальное ключевое слово к этим методам в тестовых классах.
источник