在C#中禁止"永远不会使用"和"永远不会分配"警告

Ant*_*nes 105 c# suppress-warnings visual-studio

我在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
}
Run Code Online (Sandbox Code Playgroud)

ang*_*son 192

是的,可以抑制这些.

通常,我反对压制警告,但在这种情况下,用于互操作的结构绝对需要一些字段存在,即使你从未打算(或可以)使用它们,所以在这种情况下我认为它应该是合理的.

通常,要抑制这两个警告,您可以修复有问题的代码.第一个("......从未使用过")通常是代码早期版本的剩余代码味道.也许代码被删除了,但是遗留下来的字段.

第二种通常是错误使用字段的代码气味.例如,您可能会错误地将属性的新值写回属性本身,从不写入支持字段.


要禁止显示" 永远不使用字段XYZ ",请执行以下操作:

#pragma warning disable 0169
... field declaration
#pragma warning restore 0169
Run Code Online (Sandbox Code Playgroud)

要禁止显示" 永远不会将字段XYZ分配给,并且将始终具有其默认值XX "的警告,请执行以下操作:

#pragma warning disable 0649
... field declaration
#pragma warning restore 0649
Run Code Online (Sandbox Code Playgroud)

要自己找到这样的警告号码(即我怎么知道使用0169和0649),你这样做:

  • 正常编译代码,这将在Visual Studio中向错误列表添加一些警告
  • 切换到Output窗口和Build输出,并寻找相同的警告
  • 复制相关消息中的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找到相应的文件之前.最小化禁用这些警告的行数.上面的模式仅禁用一行警告.
  • 此外,正如乔恩所提到的,关于你为什么这样做的评论是一个好主意.在没有原因的情况下禁用警告绝对是代码嗅觉,并且评论将阻止未来的维护者花时间或者想知道你为什么这样做,或者甚至通过删除它并尝试修复警告.

  • 我进一步建议上面的答案,禁用的范围尽可能小(避免在有用的地方禁用它),并始终伴随禁用评论为什么你禁用,例如` //在这种情况下为interop`存在. (9认同)
  • 正如乔恩所说,评论"为什么"非常重要.另外,我通常将警告消息的至少部分文本添加到评论中,例如//抑制"永远不会分配给..."警告.保护未来的维护者不得不查看警告代码 - 毕竟,它可能是你! (2认同)
  • 评论说,对于Unity3D用户,私有字段的警告编号为0414,局部变量的警告编号为0219,而不是169(这会引发有关无法恢复警告的警告). (2认同)

flo*_*ele 14

修复这些警告的另一个"解决方案"是制作结构public.然后不会发出警告,因为编译器无法知道在程序集外部是否正在使用(分配)字段.

也就是说,"互操作"组件通常不应该是公开的,而是internal或者private.

  • 很好,这确实隐藏了警告......但是将这样的`struct`设置为`public`比我们试图掩盖的警告更可能是一个错误.(您可能不应该不必要地暴露用于内部实现的类型,并且具有公共字段的类型可能不属于公共API).只是为了强化你的建议,这些类型应该是"相当"内部`或"私人"";-). (2认同)

Pen*_*hev 5

我得到了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
}
Run Code Online (Sandbox Code Playgroud)