«Считать все предупреждения ошибками, кроме…» в Visual Studio

124

В Visual Studio я могу выбрать параметр «Обрабатывать предупреждения как ошибки», чтобы предотвратить компиляцию моего кода при появлении каких-либо предупреждений. Наша команда использует эту опцию, но есть два предупреждения, которые мы хотели бы сохранить как предупреждения.

Есть возможность подавить предупреждения, но мы НЕ хотим, чтобы они отображались как предупреждения, так что это не сработает.

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

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

Кто-нибудь знает, как это сделать лучше?


Разъяснение для тех, кто не сразу понимает, почему это полезно. Подумайте о том, как работает большинство предупреждений. Они говорят вам, что в коде, который вы только что написали, что-то не так. На их исправление уходит около 10 секунд, и это сохраняет базу кода более чистой.

Предупреждение «Устаревшее» сильно отличается от этого. Иногда для его исправления нужно просто использовать новую сигнатуру метода. Но если весь класс устарел, и вы используете его, разбросанный по сотням тысяч строк кода, на исправление может потребоваться несколько недель или больше. Вы не хотите, чтобы сборка ломалась так долго, но вы определенно хотите видеть предупреждение об этом. Это не просто гипотетический случай - это случилось с нами.

Буквальные предупреждения "#warning" также уникальны. Я часто хочу проверить это, но не хочу ломать сборку.

Нил
источник
Не могли бы вы поставить пробелы в своем большом списке чисел? Он забил упаковку строки.
Рэй,
Боже, я ненавижу сложные правила, которые составляются людьми, часто для того, чтобы успокоить эго конкретного человека.
Jon Limjap
21
Я понимаю его точку зрения об устаревшем предупреждении, это не произвольно.
Эд С.
По моему опыту, включение хотя бы одного предупреждения в вашу сборку похоже на добавление первого async / await. Скоро их будут десятки. Я помню, что при всех настройках разработчик может видеть менее 10 предупреждений в окне списка ошибок в VS. Могу поспорить, что как только у вас будет более 5 предупреждений, подавляющее большинство разработчиков в команде не смогут обнаружить новое - в вашей настройке это означает, что они не заметят предупреждения о том, что метод устарел, что противоречит вся цель - предупредить :) Каков твой опыт общения с этим Нилом?
tymtam
@mayu, это загадка. Много раз я видел, как предупреждения долгое время игнорировались. Но в итоге либо вы показываете предупреждение, либо вообще ничего не показываете. Если вы показываете предупреждение, по крайней мере, есть шанс, что кто-то узнает из него что-то полезное. Если вы относитесь к большинству предупреждений как к ошибкам, то немногие из оставшихся могут привлечь больше внимания.
Нил

Ответы:

155

Вы можете добавить WarningsNotAsErrors-tag в файл проекта.

<PropertyGroup>
    ...
    ...
    <WarningsNotAsErrors>618,1030,1701,1702</WarningsNotAsErrors>
</PropertyGroup>

Примечание: 612и 618оба являются предупреждениями об устаревшем, не знаю разницы, но проект, над которым я работаю, сообщает об устаревшем с предупреждением 618.

SvenL
источник
24
Разница между 612 и 618 - это комментарий ObsoleteAttribute. Атрибут ObsoleteAttribute без комментария генерирует ошибку 612, а атрибут с комментарием
Марко Спатц,
@MarcoSpatz Именно. Затем мы можем рассматривать [Obsolete]элементы, для которых установлено значение messageis, nullкак ошибки, в то время как мы позволяем тем, для которых messageустановлено значение, оставаться только предупреждениями. Если для errorпараметра установлено значение trueв ObsoleteAttribute, вместо него создается CS0619. Кажется, что это не работает, если messageесть null(но кто бы все [Obsolete(null, true)]равно сделал ?).
Jeppe Stig Nielsen
Для F # используйте --warnaserror-:618,1030 в поле Build-> Other flags. Этот вариант проекта еще не реализован для проектов F #. github.com/Microsoft/visualfsharp/issues/3395
Asik,
2
Полезно знать, что существует "WarningsNotAsErrors". Он должен быть доступен в настройках проекта без необходимости редактировать файл вручную. Спасибо.
AFract
1
Microsoft действительно облажалась (и 11 лет спустя ничего не исправила!). Изменены настройки проекта <NoWarn>, которые в большинстве случаев являются второстепенными и не вносятся <WarningsNotAsErrors>в пользовательский интерфейс. Престижность.
user2864740
13

/ warnaserror / warnaserror-: 618


источник
1
Спасибо за ваш вклад. Несмотря на то, что они не решают проблему IDE, на данный момент это самые полезные комментарии.
Нил
2
Куда это добавить?
чечо 07
@checho, эти переключатели будут добавлены в командную строку при вызове msbuild. Для наших целей более полезен верхний ответ, потому что мы можем встроить его в проект, вместо того, чтобы изменять способ вызова msbuild.
Нил
Не работает с MSBuild 15.9.21 + g9802d43bc3: MSBUILD : error MSB1001: Unknown switch. Switch: /warnaserror-:618
Paul B.
3

или, точнее, в вашем случае:

/ warnaserror / warnaserror-: 612,1030,1701,1702

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


источник
1

Почему вы хотите видеть предупреждения, которые не рассматриваются как ошибки? Я не понимаю, почему это желательно - либо вы их исправляете, либо нет.

Будут ли работать два разных файла сборки / решения - или сценарий для копирования одного, а затем изменить уровень предупреждений / предупреждений будет подходящим. Кажется, что, возможно, вы хотите, чтобы некоторые исполнения компилятора кричали, но другие вы хотите продолжить.

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

Тим
источник
7
Большинство предупреждений происходит из-за простой путаницы в моем коде (например, я объявил переменную, которую не использую). Предупреждение «Устаревшее» часто возникает из-за изменения чужого кода. На исправление этого может потребоваться несколько недель разработки. #warning - это предупреждение, которое я хочу включить в код (вероятно, долгосрочное исправление).
Нил
4
Другими словами, есть предупреждения о том, что я не хочу ломать свою сборку. Если #warning нарушает сборку, то я никогда не смогу зарегистрировать ее. Если Obsolete нарушит сборку, то другая команда, от которой мы зависим, может неосознанно нарушить сборку нашей команды, просто добавив устаревший атрибут.
Нил
@Neil Я согласен с некоторыми из ваших аргументов, но удаление неиспользуемого var не занимает много времени, и вы определенно хотите знать, что другая команда сделала что-то устаревшим.
tymtam
@mayu, спасибо за комментарий. Я согласен насчет вар, который вы не используете. Вот почему я бы хотел, чтобы компилятор рассматривал это как ошибку. Я также согласен, что вы хотите знать, когда что-то устарело. Но если рефакторинг чего-то устаревшего в вашем коде занимает слишком много времени, вы можете выбрать один из следующих вариантов: 1) Относитесь к этому предупреждению как к предупреждению 2) Пусть ваша сборка остается неработающей в течение длительного времени 3) Другое решение, например, отключение предупреждений как ошибок. Если большинство предупреждений являются ошибками, ваш список предупреждений, скорее всего, останется коротким, поэтому вы с большей вероятностью заметите, когда они появятся. Какое решение вы предпочитаете?
Нил
1
@mayu, другая команда (будь то в той же компании или за ее пределами) может законно захотеть сообщить, что класс, метод, другой компонент поэтапно сокращается в течение некоторого периода времени. Добавление атрибута - хороший способ сообщить об этом потребителям библиотеки. Я не считаю это трудным. Фактически, добавление атрибута как можно раньше - хороший способ убедиться, что другие знают о будущих изменениях.
Нил
1

Я использую рассматривать предупреждения как ошибки.

В редких случаях, когда появляется какое-либо допустимое предупреждение (например, ссылка на устаревший член или отсутствие документации по классам сериализации XML), его необходимо явно подавить с помощью #pragma disable (и, при необходимости, может быть причина отсутствия чистого кода. в качестве комментария).

Наличие данной директивы также позволяет узнать, кто принял данное предупреждение. (путем «обвинения» действия контроля версий) в случае возникновения вопросов.

Ринат Абдуллин
источник
3
Я тоже этим пользуюсь, хотя это не решает проблемы, упомянутые в моем описании. Я хочу, чтобы определенные предупреждения рассматривались как предупреждения, а не скрывались.
Нил
0

Почему бы просто не иметь правило, гласящее: «Тот, кто проверяет код с любым предупреждением внутри него, кроме 612, 1030, 1701 или 1702, должен подойти к доске и сто раз написать:« Я больше не буду проверять код с запрещенными предупреждениями ». «»

erikkallen
источник
9
Удачи в реализации этого ... Обработка предупреждений как ошибок - очень важный шаг для повышения общего качества кода, и это заставит разработчиков фактически исправить свой код! Да здравствует автоматизация, ручной труд - это такой 20 век: иш!
Андреас Магнуссон
@AndreasMagnusson Если бы только отсутствие предупреждений действительно гарантировало качество кода ..
user2864740
2
@ user2864740: Согласен, серебряных пуль нет. Но слишком распространенное заблуждение - отвергать что-то полезное на том основании, что это не серебряная пуля.
Андреас Магнуссон
-4

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

Логическим решением было бы либо 1) запретить проверки, если код не компилируется (что означает, что те, кто создал предупреждения, должны будут исправить их, поскольку, по сути, они нарушили сборку), либо 2) рассматривать предупреждения как предупреждения. Создайте две конфигурации сборки, одну, которая обрабатывает предупреждения как ошибки, которые можно запускать регулярно, чтобы гарантировать, что код не содержит предупреждений, а другую, которая обрабатывает их только как предупреждения и позволяет вам работать, даже если кто-то другой представил предупреждение.

jalf
источник
1
Используя выбранный ответ, легко добавить к списку предупреждений, рассматриваемых как предупреждения. Это работает намного лучше, чем любое из предложенных вами решений. Очевидно, что предупреждения не являются ошибками, но обработка большинства предупреждений как ошибок означает, что код никогда не будет зарегистрирован с этими предупреждениями.
Нил