Подавление "никогда не используется" и "никогда не назначается" предупреждениям в С#

У меня есть файл HTTPSystemDefinitions.cs в проекте С#, который в основном описывает более старые окна ISAPI для потребления управляемым кодом.

Это включает в себя полный набор структур, относящихся к ISAPI, не все или которые потребляются кодом. При компиляции все члены полей этих структур вызывают предупреждение, подобное следующему: -

Предупреждающее поле 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.SetHeader' никогда не назначается и всегда будет иметь значение по умолчанию null

или

Предупреждение Поле "UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.HttpStatus" никогда не используется

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

Edit

Пример struct: -

struct HTTP_FILTER_PREPROC_HEADERS
{
    //
    //  For SF_NOTIFY_PREPROC_HEADERS, retrieves the specified header value.
    //  Header names should include the trailing ':'.  The special values
    //  'method', 'url' and 'version' can be used to retrieve the individual
    //  portions of the request line
    //

    internal GetHeaderDelegate GetHeader;
    internal SetHeaderDelegate SetHeader;
    internal AddHeaderDelegate AddHeader;

    UInt32  HttpStatus;               // New in 4.0, status for SEND_RESPONSE
    UInt32  dwReserved;               // New in 4.0
}

Ответ 1

Да, они могут быть подавлены.

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

Обычно, чтобы подавить эти два предупреждения, вы исправите нарушающий код. Первый ( "... никогда не используется" ), как правило, является кодовым запахом остатков из более ранних версий кода. Возможно, код был удален, но поля остались позади.

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


Чтобы подавить предупреждения для " Поле XYZ никогда не используется", вы делаете это:

#pragma warning disable 0169
... field declaration
#pragma warning restore 0169

Чтобы подавить предупреждения для " Поле XYZ никогда не назначается и всегда будет иметь значение по умолчанию XX", вы делаете это:

#pragma warning disable 0649
... field declaration
#pragma warning restore 0649

Чтобы найти такие номера предупреждений самостоятельно (например, как я знал, чтобы использовать 0169 и 0649), вы делаете это:

  • Скомпилируйте код как обычно, это добавит некоторые предупреждения в ваш список ошибок в Visual Studio
  • Переключитесь в окно "Выход" и "Вывод сборки" и выполните поиск тех же предупреждений
  • Скопируйте 4-значный код предупреждения из соответствующего сообщения, которое должно выглядеть следующим образом:

    C:\Dev\VS.NET\ConsoleApplication19\ConsoleApplication19\Program.cs(10,28):     предупреждение CS 0649: Поле 'ConsoleApplication19.Program.dwReserved' никогда не     присвоенный и всегда будет иметь значение по умолчанию 0


Caveat: согласно комментарию @Jon Hanna, возможно, для этого есть несколько предупреждений, для будущих искателей этого вопрос и ответ.

  • Во-первых, и прежде всего, действие подавления предупреждения сродни проглатыванию таблеток для головной боли. Конечно, иногда это может быть правильным, но это не решение. Иногда головная боль является настоящим симптомом, который вы не должны маскировать, то же самое с предупреждениями. Всегда лучше попробовать обработать предупреждения, исправив их причину, а не просто слепо удалить их из вывода сборки.
  • Сказав это, если вам нужно подавить предупреждение, следуйте шаблону, который я изложил выше. Первая строка кода #pragma warning disable XYZK отключает предупреждение для остальной части этого файла или, по крайней мере, до тех пор, пока не будет найден соответствующий #pragma warning restore XYZK. Минимизируйте количество строк, на которые вы отключили эти предупреждения. Шаблон выше отключает предупреждение только для одной строки.
  • Кроме того, как упоминает Джон, комментарий о том, почему вы это делаете, - хорошая идея. Отключение предупреждения, безусловно, является кодовым запахом, когда это делается без причины, и комментарий не позволит будущим сопровождающим тратить время или задаваться вопросом, почему вы это сделали, или даже удалив его и пытаясь исправить предупреждения.

Ответ 2

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

Тем не менее, компоненты "interop" обычно не являются общедоступными, а скорее internal или private.

Ответ 3

Я получил VS для создания скелета реализации для System.ComponentModel.INotifyPropertyChanged, и события были реализованы как поля, которые вызвали предупреждения CS0067.

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

Это имеет смысл, поскольку синтаксический синтаксис объявления свойств компилируется в поле, а также методы getter и/или setter (добавьте/удалите в моем случае), которые ссылаются на это поле. Это удовлетворяет компилятору, и предупреждения не возникают:

struct HTTP_FILTER_PREPROC_HEADERS
{
    //
    //  For SF_NOTIFY_PREPROC_HEADERS, retrieves the specified header value.
    //  Header names should include the trailing ':'.  The special values
    //  'method', 'url' and 'version' can be used to retrieve the individual
    //  portions of the request line
    //

    internal GetHeaderDelegate GetHeader {get;set;}
    internal SetHeaderDelegate SetHeader { get; set; }
    internal AddHeaderDelegate AddHeader { get; set; }

    UInt32 HttpStatus { get; set; }               // New in 4.0, status for SEND_RESPONSE
    UInt32 dwReserved { get; set; }               // New in 4.0
}

Ответ 4

У пользователей C/С++ есть (void)var; для подавления предупреждений неиспользуемых переменных. Я только что обнаружил, что вы также можете подавлять предупреждения неиспользуемых переменных в С# с побитовыми операторами:

        uint test1 = 12345;
        test1 |= 0; // test1 is still 12345

        bool test2 = true;
        test2 &= false; // test2 is now false

Оба выражения не генерируют неиспользуемые предупреждения переменных в компиляторах VS2010 С# 4.0 и Mono 2.10.