Можете ли вы использовать nameof когда скрыто в элементе видимости?
Рассмотрим следующий устаревший код:
public class Foo
{
public void Blah(string frob)
{
if (frob == null)
throw new ArgumentException("frob");
}
public string nameof()
{
//boring code
}
}
Теперь представьте, что часть этого кода подвергается рефакторингу, и мы хотим провести рефакторинг Blah
следующим образом:
public void Blah(string frob)
{
if (frob == null)
throw new ArgumentException(nameof(frob)); //nameof contextual keyword
}
Этот парсер не выберет контекстное ключевое слово nameof
и разрешу частному методу nameof
выдача ошибки времени компиляции (без существующей перегрузки). Зачем? Я бы понял это, если бы метод был nameof(object o)
,
Есть ли способ, которым я могу разрешить компилятору встроить nameof
? Нужно ли реорганизовать код, переименовывая метод?
Приведенный выше пример является очень упрощенным сценарием, на самом деле nameof
Этот метод широко используется в рефлексии, и потребуется время и усилия, чтобы убедиться, что переименование было сделано правильно везде.
3 ответа
Этот анализатор не выберет контекстное ключевое слово nameof и преобразуется в закрытый метод nameof, сообщающий об ошибке времени компиляции (без существующей перегрузки). Зачем?
Вопросы "почему" расплывчаты; Я собираюсь предположить, что вопрос означает: "Какие конструктивные соображения принимаются во внимание при разработке таких функций?"
При создании нового контекстного ключевого слова следует учитывать, что ни одна из существующих программ не меняет смысл при компиляции в новом компиляторе. Например, когда я написал код для добавления var
в C# 3 мы тщательно следили за тем, чтобы
class var { public implicit operator var(int x) { ... } }
...
var y = 3;
назначает тип var
в y
, и не int
, Хотя такие программы маловероятны, мы не хотим никого сломать.
Точно так же синтаксис для yield return
было yield return
а не просто yield
потому что * ни одна программа не была yield return
в этом. Но многие программы могли бы сказать, yield(123);
Точно так же await
оператор только имеет смысл, когда внутри async
метод и from
а также select
и так далее, имеют смысл в понимании запросов.
таким образом nameof
должен означать идентификатор с именем nameof
если один находится в области, а не оператор. Обратите внимание, что C# не пытается вернуться назад. Он не говорит "ну, это по объему, но это вызывает ошибку разрешения перегрузки, поэтому я собираюсь вернуться и предположить, что это ключевое слово..." Нет, нет, это ужасное рассуждение. Идентификатор nameof
находится в области видимости и, следовательно, это почти наверняка программа до C# 6. Вероятность 99,9% состоит в том, что каждое использование nameof
в этой программе намеревается обратиться к идентификатору.
Основной принцип проектирования C# - "если что-то выглядит странно, сообщите разработчику, чтобы он знал о проблеме ". Теперь вы хорошо знаете, что в вашей программе есть серьезная проблема, и теперь вы можете попытаться ее исправить. C# не предназначен для нахождения какой-либо возможной интерпретации вашей программы, которая компилируется, какой бы странной и маловероятной она ни была.
Я думаю, что поиск кода для отражения nameof
в классе для чего-то, что может быть как-то похоже на платформу сериализации...
В этом случае, возможно, лучшим временным решением было бы обновить этот код, чтобы сначала выполнить поиск функции. NameOf
и если этого не существует, ищите наследие nameof
,
Таким образом, вы сможете найти свой код по одному классу за раз.
Если вы хотите сделать полное исправление сразу и при условии, что ваш заказ nameof
функция никогда не принимает никаких аргументов, тогда лучшее решение, вероятно, переименовать все nameof
один раз NameOf
(или любое другое имя, которое вам нравится), а затем исправьте ошибку компиляции, когда nameof
должен быть использован. Это имело бы смысл, если у вас много кода и вы только начинаете использовать nameof
оператор.
В любом случае, было плохой идеей не следовать соглашению об именах.NET, особенно для такого короткого имени, которое в какой-то момент может стать ключевым словом.
Может быть, было бы неплохо иметь обзор кода, чтобы те, кто пишет плохой код, исправляли его до ухода из компании.
Независимо от того, можете ли вы заставить код использовать ключевое слово nameof вместо встроенной функции, вам не следует использовать ключевое слово в качестве имени метода. Переименуйте имя метода.