Как отключить неявное «это» в C #? - PullRequest
7 голосов
/ 05 июня 2009

Это меня очень беспокоит, и я нахожу, что пишу глупые ошибки в сочетании с Intellisense (VS 2008 Pro):

class Foo
{
    public Foo(bool isAction)
    {
        this.IsAction = IsAction;
    }

    public bool IsAction { get; private set; }
}

Вы поймали это? Я, конечно, не сделал, пока IsAction никогда не изменился, вызывая ошибки.

Intellisense каким-то образом преобразовал "isA<tab>" в "IsAction" для меня, что означает, что свойство Foo.IsAction равно всегда false независимо от входных данных конструктора. Просто великолепно.

Я должен сказать, что я особенно ненавижу "неявное this" (я не знаю, имеет ли оно формальное имя), и я хотел бы отключить его, чтобы оно никогда не принималось. Есть ли способ сделать это? Это также относится к вызову статических методов того же класса.

В качестве альтернативы, какие соглашения об именах позволяют избежать этой маленькой проблемы? Свойство должно оставаться "IsAction", поэтому оно должно быть соглашением по имени параметра конструктора. Как ни странно, если я назову его с точно совпадающим написанием, то this.IsAction = IsAction; сработает правильно.

Проблема не в регистрозависимых языках, а в неявности this. Теперь, когда я думаю об этом, это также больше вопрос VS 2008 Pro, чем C #. Я могу жить с кодом, уже написанным без this, но я не хочу писать новый код без него, что означает сообщение In


Ответ Нолдорина заставил меня задуматься.

Теперь, когда я думаю об этом, это также больше вопрос VS 2008, чем C #. Я могу жить с кодом, уже написанным без this (хотя я изменяю его, если я там слоняюсь по кругу), но я не хочу писать новый код без него, что означает приказ Intellisense прекратить это делать. Могу ли я сказать Intellisense, чтобы он сбил его?

Ответы [ 10 ]

6 голосов
/ 06 июня 2009

Я только что попробовал ваш код в Visual Studio 2008. Включение встроенного статического анализа приводит к следующей ошибке:

Предупреждение 3 CA1801: Microsoft.Usage: Параметр isAction of 'Foo.Foo (bool)' никогда не используется. Удалить параметр или использовать его в методе корпус.

Мое предложение заключается в том, что, включив это, вы обнаружите ошибки, подобные этой на ранней стадии. Чтобы включить это, выберите свойства в контекстном меню проекта, затем перейдите на вкладку «Анализ кода» и выберите «Включить анализ кода при сборке»

4 голосов
/ 05 июня 2009

Вы всегда можете вернуться к венгерской нотации [я готовлюсь вспыхнуть, когда набираю это]. Если вы справитесь с уродством, это решит вашу проблему. Это предложение, а не рекомендация.

С другой стороны, я чертовски уверен, что статический анализ кода поймает это и предупредит вас об этом. Попробуйте FxCop.

EDIT

Я использую Resharper уже больше года, и я знаю, что он очень умно помогает вам с учетом регистра. Помимо прочих преимуществ, ваша проблема с intellisense будет решена установкой Resharper.

РЕДАКТИРОВАТЬ 2

Я только что проверил. Ни FxCop, ни Resharper не улавливают эту ошибку напрямую. То, что оба ловят, так это то, что параметр isAction не используется в методе Foo. В этом случае предупреждение будет подсказывать вам ошибку. В тех случаях, когда параметр используется другим способом в методе, он может проскользнуть через статический анализ кода.

3 голосов
/ 06 июня 2009

Это распространенная проблема. У Microsoft есть рекомендации для имен параметров , но они не очень полезны в вашем случае.

Как уже упоминали другие респонденты, вы не можете "отключить" поведение разрешения области действия языка C # - ваш лучший подход - это соглашения об именах. Другие упоминают «венгерскую» нотацию - у некоторых людей возникает коленная реакция на это из-за путаницы с первоначальным намерением нотации.

Мой личный подход состоял в том, чтобы использовать символ 'p' в качестве префикса для имен параметров открытых функций. Это ненавязчиво, просто, легко идентифицируемо и легко реализуемо с помощью таких инструментов, как Resharper .

Конкретное соглашение об именовании, которое вы выбираете, является вопросом предпочтений и стиля; однако есть некоторая выгода от того, что вы будете последовательны в выбранной вами практике.

Используя мое предложенное соглашение об именах, вы бы написали свой конструктор:

class Foo
{
    public Foo(bool pIsAction)
    {
        this.IsAction = pIsAction;
    }

    public bool IsAction { get; private set; }
}
2 голосов
/ 06 июня 2009

FxCop будет жаловаться на это, потому что параметр isAction никогда не используется. В частности это будет тянуть правило CA1801: ReviewUnusedParameters.

Лично я всегда чувствовал, что компилятор C # должен выдавать предупреждение о неиспользуемых параметрах.

1 голос
/ 05 июня 2009

Боюсь, что нет способа отключить функцию "неявного this". Это часть спецификации языка и компилятора, и нет возможности отключить его.

Лично я не считаю это большой проблемой. Конечно, важно быть осторожным с использованием заглавных букв в именах элементов и параметров, но это всегда происходит в чувствительном к регистру языке, таком как C #.

Мое рекомендуемое «решение» (которое вы, похоже, уже делаете) - всегда использовать ключевое слово this для ссылки на свойства / поля, чтобы оно сразу выделялось при использовании параметра. Это не решит проблему для вас, но если вы будете иметь это в виду, это, несомненно, поможет. Простая привычка к этому (а также запоминание все имена параметров / локальных переменных должны начинаться со строчной буквы ) помогут вам избежать этой проблемы в будущем.

1 голос
/ 05 июня 2009

Это заставляет меня все время. Я привык к тому, что переменные передаются в конструктор с помощью символа _, например:

class Foo
{    
    public Foo(bool _isAction)
    {
        this.IsAction = _isAction;
    }
    public bool IsAction { get; private set; }}
0 голосов
/ 06 июня 2009

Примечание:

Если вы используете Resharper, у вас есть несколько ярлыков, которые пишут для вас большую часть этого кода и избегают ошибок.

Вы можете сначала создать свойство, затем нажать Alt-Ins и выбрать «создать конструктор», или вы можете добавить параметр «isAction» в конструктор, нажать Alt-Enter с помощью каретки в параметре имя и выбрать Действие «Создать и инициализировать автоматическое свойство IsAction» из всплывающего меню.

0 голосов
/ 05 июня 2009

Это может раздражать в других возможностях, но вы можете отключить опцию, чтобы Intellisense предварительно выбирал последнего использовавшегося участника. Я понимаю, что это на самом деле не решит проблему напрямую, но, возможно, поможет предотвратить некоторые случайные вкладки, если вы не выбрали нужный элемент.

0 голосов
/ 05 июня 2009

Я думаю, что более вероятно, что разработчик выбрал «IsAction» вместо «isAction» от Intellisense. Я не думаю, что Intellisense изменит "isA" на "this.IsAction".

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

0 голосов
/ 05 июня 2009

Это раздражающая проблема в intellisense Visual Studio. Resharper понимает это правильно большую часть времени.

...