C#で「決して使用されない」および「割り当てられない」警告の抑制


107

C#プロジェクトにHTTPSystemDefinitions.csファイルがあり、マネージコードが使用する古いWindows ISAPIを基本的に記述しています。

これには、ISAPIに関連するすべてではない、またはコードによって使用される構造の完全なセットが含まれます。コンパイル時に、これらの構造のすべてのフィールドメンバーが次のような警告を引き起こしています。

警告フィールド 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.SetHeader'は割り当てられず、常にデフォルト値nullになります

または

警告フィールド 'UnionSquare.ISAPI.HTTP_FILTER_PREPROC_HEADERS.HttpStatus'は決して使用されません

これらを無効にできます#pragma warning disableか?もしそうなら、対応するエラー番号は何でしょうか?そうでない場合、他に何かできることはありますか?このファイルに対してこれを行うのは私だけであることを覚えておいてください。重要なのは、他のファイルからのこのような警告が表示されることです。

編集する

構造体の例:-

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
}

それらのフィールドの宣言、またはそれらが入っている構造体を示すことができますか?すなわち。例を挙げる。
Lasse V. Karlsen

11
これらが相互運用性の定義である場合は、通常[StructLayout(LayoutKind.Sequential)]、メモリレイアウトが正しいことを確認するために配置します(現在の実装では、この属性がない場合でも、属性は保証されません)。私が正しく覚えている場合、C#コンパイラはこの属性の存在を検出し、相互運用のためにフィールドが存在する必要があることを認識しているため、これらの警告を自動的に抑制します。(私はこれについて間違っている可能性があるため、回答ではなくコメントとして投稿します)。
グレッグブナ

@グレッグ:それは私が調査するのに役立つ情報です私はむしろそれらを抑制するのではなく警告が生成されないようにしたいと思います。
AnthonyWJones 2010年

1
を使用するための+1 StructLayout。警告自体を抑制するよりもクリーンなようです。
Deanna 2014年

@GregBeechそうですね!それは、VS2017の.NET Standardプロジェクトにも適用されます。
zwcloud 2017

回答:


195

はい、これらは抑制できます。

通常、私は警告を抑制することに反対していますが、この場合、相互運用に使用する構造体は、使用するつもりがない(または使用できない)場合でも、いくつかのフィールドが存在することを絶対に必要とするため、この場合は正当化する必要があると思います。

通常、これらの2つの警告を抑制するには、問題のコードを修正します。最初の(「...は使用されない」)は、通常、以前のバージョンのコードからの残り物のコード臭です。おそらくコードは削除されましたが、フィールドは残されました。

2番目は通常、誤って使用されたフィールドのコード臭です。たとえば、プロパティの新しい値をプロパティ自体に誤って書き込み、バッキングフィールドには決して書き込まない場合があります。


フィールド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になります


警告@Jon Hannaのコメントによると、この質問と回答の将来の発見者のために、おそらくいくつかの警告がこれのためにあります。

  • まず第一に、警告を抑制する行為は、頭痛のために錠剤を飲み込むことに似ています。確かに、それは時には正しいことかもしれませんが、万能の解決策ではありません。時々、頭痛は警告と同じように、マスクすべきではない実際の症状です。警告をビルド出力から盲目的に削除するのではなく、原因を修正して警告を処理することを常にお勧めします。
  • そうは言っても、警告を抑制する必要がある場合は、上に示したパターンに従ってください。最初のコード行は#pragma warning disable XYZKそのファイルの残りの部分に対する警告無効にするか、少なくとも対応するもの#pragma warning restore XYZKが見つかるまで無効にします。これらの警告を無効にする行の数を最小限に抑えます。上記のパターンは、1行のみの警告を無効にします。
  • また、Jonが述べているように、なぜこれを行っているのかについてのコメントは良い考えです。警告を無効にすることは、理由なしに行われると間違いなくコード臭であり、コメントは、将来のメンテナがなぜそれをしたのかと思ったり、警告を削除して警告を修正しようとしたりすることに時間を費やすことを防ぎます。

9
私は、例えば、可能な限り小さく(どこかで、それは便利です、それを無効にすることを回避するため)、常にあなたは無効にしている理由としてコメントを無効に同行するなど無効BEの範囲という、上記の回答にはさらにお勧め//exists for interopでこの場合。
Jon Hanna

どうもありがとう。VSの[エラーリスト]ウィンドウにこれらの数値の列が含まれていないのは奇妙な選択です。
AnthonyWJones 2010

2
ジョンが言うように、「なぜ」をコメントすることは非常に重要です。さらに、私は通常、警告メッセージのテキストの少なくとも一部をコメントに追加します。たとえば、「「割り当てられない...」警告を抑制します。将来のメンテナーが警告コードを調べなければならないという煩わしさを省いてください-結局のところ、それはあなたかもしれません!
トムBushell

1
すぐにはわかりませんが、出力ウィンドウでCTRL + Fを使用して[検索]を使用し、「警告」と入力し、[すべて検索]をクリックすると、警告番号が表示され、すべての警告をすばやく取得できます。とは[StructLayout(LayoutKind.Sequential)]いえ、質問に対するGreg Beechのコメントに従って、属性は相互運用をより適切に処理します。
Ryan Buddicom 2014年

2
Unity3Dユーザーの場合、警告番号はプライベートフィールドでは0414、ローカル変数では0219であり、169ではありません(代わりに警告を復元できないという警告がスローされます)。
Draco18sは、2017

14

これらの警告を修正するもう1つの「解決策」は、構造体を作成することpublicです。その場合、コンパイラーがフィールドがアセンブリーの外部で使用(割り当て)されているかどうかをコンパイラーが認識できないため、警告は発行されません。

とはいえ、「相互運用」コンポーネントは通常パブリックではなく、internalまたはである必要がありprivateます。


2
ニースは、これは非表示に警告し...しかし、このようなAを設定するstructpublic、我々はマスクしようとしている警告よりも間違いである可能性が高いです。(内部実装に使用される型を不必要に公開してはならず、パブリックフィールドを持つ型はパブリックAPIに属していない可能性があります)。そのようなタイプは「どちらinternalかと言えば」であるというアドバイスを強化するためだけprivateです;-)。
binki 2014年

本当にありがとう-これが私が必要としたものです。私は使用JsonConvert.DeserializeObjectしていて、すべてのプロパティが公開されているだけのパブリッククラスに逆シリアル化して、何が返されるかを理解しています。すべてのパブリック文字列で空のパブリッククラスにするだけで、短いコードで警告がなくなります。配列の内容を明示的に指定する必要がないため、動的クラスを使用する方が良いかもしれませんが、これは、オブジェクトを使用することを希望する人にとっては良い参照になると思います。
user1274820

6

VSに実装スケルトンを生成させ、System.ComponentModel.INotifyPropertyChangedイベントはCS0067警告をトリガーするフィールドとして実装されました。

受け入れられた回答で与えられた解決策の代わりとして、フィールドをプロパティに変換し、警告が消えました

プロパティ宣言構文シュガーはフィールドに加えてフィールドを参照するゲッターおよび/またはセッターメソッド(私の場合は追加/削除)にコンパイルされるため、これは理にかなっています。これはコンパイラーを満たし、警告は出されません:

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
}

あなたのソリューションは警告を無効にするよりはるかに優雅ですが、MarshalAsAttributeなどの一部のフィールドのみの属性に干渉する可能性があります。
HuBeZa

1
情報:この状況で生成される実際のプライベートフィールドには、<GetHeader>k__BackingField使用されるC#コンパイラの実装の詳細によっては、などの「奇妙な」名前が付いている場合があります。
Jeppe Stig Nielsen 2015

1

C / C ++ユーザーは(void)var;、未使用の変数の警告を抑制する必要があります。C#でビットごとの演算子を使用して未使用の変数の警告を抑制できることを発見しました。

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

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

どちらの式も、VS2010 C#4.0およびMono 2.10コンパイラで未使用の変数警告を生成しません。


4
以下のための作品uintとして、他のタイプのためにではなくException。C / C ++に相当する一般的なトリックを知っていますvar;か?
manuell 2015年

1
@manuell未来からこんにちは!error.ToString();タイプの変数に使用できますException
Sv443

今からありがとう。そのトリックは実行時に実際のコードを追加しますよね?
manuell
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.