如何在使用特定枚举值时生成警告

问题描述 投票:0回答:4

我正在使用由第 3 方大会公开的枚举,例如,

public enum APIEnum
{
  Val1,
  Val2
}

。但是,其中许多值会导致我的应用程序出现错误行为。如果代码中使用了这些“坏”枚举值之一,我想生成编译器警告,例如,

APIEnum usedVal = APIEnum.Val2;

Compiler Warning: APIEnum.Val2 causes incorrect behavior.

我的最终目标是生成一个警告,如果使用了错误的值(占总体情况的 2%),则必须有意识地 #pragma'd。否则,会出现警告,并且由于我们将警告视为错误,因此会中断编译,直到修复或 #pragma'd。

我查看了有关使用 Obsolete 属性来解决此问题的线程 herehere,但我担心 Obsolete 会引起混乱,因为该值并不是真正过时。

我考虑过使用Resharper代码分析插件来解决问题的可能性,这绝对是一个选择。我不是 Resharper 或如何通过 Resharper 最好地解决问题的专家。

c# visual-studio resharper code-analysis fxcop
4个回答
2
投票

您可以在 ReSharper 中使用结构搜索。转到

ReSharper -> Options | Code Inspection -> Custom patterns
,单击
Add Pattern
,在
APIEnum.Val2
字段中输入
Search pattern
,然后在
Description
中输入错误描述。将模式严重性设置为
Show as error
。单击
Add
。就这样。唯一的缺点是,如果您的项目中存在另一个具有相同
APIEnum
值的
Val2
,即使在不同的命名空间中,那么它也会被标记为错误。

您还应该打开

ReSharper -> Options | Code Inspection -> Settings | Analyse errors in whole solution
以显示每个文件中的错误。


2
投票

您可以为此创建自定义代码分析 (FxCop) 规则,或者实际上推出您自己的 Resharper 规则。自定义代码分析规则应该相对简单,查看我的规则,该规则检查正则表达式是否编译,它会找到

RegexOptions
枚举的所有用途。您应该能够从那里构建自己的自定义规则。

自定义代码分析规则的一般优秀网站:

如果您在编写自己的规则时遇到困难,请随时分享到目前为止的代码以寻求更具体的帮助。

使用 VisitAssignment 语句,然后使用

assignment.Target.Type.FullName
获取底层枚举类型。请务必检查 Target.Type 是否为 null,委托可以有 null Type。

Introspector showing Enum Type

方法调用也会看到枚举:

Introspector showing Assignment and Methodcall


0
投票

我已经使用 FxCop 方法制作了一个解决方案原型,但我认为 FxCop 实际上无法解决它。我在规则中尝试了以下代码:

public class DoNotUseSpecificEnum : RuleBase
{
  private string[] _enumValsToCheck =
  {
    "APIEnum.Val2"
  };

  public DoNotUseSpecificEnum ()
    : base("DoNotUseSpecificEnum ") { }

  public override void VisitBinaryExpression(BinaryExpression binaryExpression)
  {
    if ( _enumValsToCheck.Contains(
      binaryExpression.Operand1.ToString()) 
      || _enumValsToCheck.Contains( binaryExpression.Operand2.ToString() ) )
    {
      this.Problems.Add(new Problem(base.GetResolution(),
        binaryExpression.SourceContext));
    }

    base.VisitBinaryExpression(binaryExpression);
  }
}

当我跟踪 VisitBinaryExpression 时,我发现 Operand1 值是“1”而不是“APIEnum.Val2”。事后看来,这是有道理的(FxCop 在 MSIL 上工作,它已用数字文字替换了枚举名称/值);我只是希望在深入研究自定义 FxCop 规则的痛苦/荣耀之前就意识到这一点。 :)

我发现的另一种方法是使用 StyleCop 进行语法分析,但这看起来更难弄清楚,而且比自定义 FxCop 规则更不受欢迎。

我将建议使用 Resharper 团队特定的自定义模式作为管理此问题的方式。我仍然担心这种方法(特别是因为我们将在多个解决方案和团队中采用相同的规则),但构建机器的问题比我想象的要小得多。 TeamCity 允许开箱即用地进行“构建时检查 Resharper 规则”,因此我们至少可以配置 CI 服务器来查找和报告尚未使用 Resharper 语法抑制的枚举的使用情况。


0
投票
Microsoft.CodeAnalysis.BannedApiAnalyzers

NuGet 包。

其文档

进行总结,将包添加到您的项目/解决方案后,将 BannedSymbols.txt 添加到您的项目/解决方案,并将其添加到您的 csproj

<ItemGroup>
  <AdditionalFiles Include="path to BannedSymbols.txt"/>
</ItemGroup>

现在您只需填写
BannedSymbols.txt

。 一行应该看起来像


{符号的文档注释 ID 字符串}[;描述文本]

考虑到您希望获得有关使用给定枚举值 (
APIEnum.Val2

) 的警告,第一部分应类似于

F:Namespace.Type.Field
,对于您的情况,它会转换为
F:ApiNamespace.APIEnum.Val2
。第二部分是可选的,可让您自定义警告消息。
例如使用 

F:ApiNamespace.APIEnum.Val2; APIEnum.Val2 causes incorrect behavior.

,执行

var x = APIEnum.Val2;
将会给您以下警告:

RS0030:符号“APIEnum.Val2”在此项目中被禁止:APIEnum.Val2 会导致不正确的行为。

© www.soinside.com 2019 - 2024. All rights reserved.