如果使用特定的枚举值,如何生成警告

时间:2013-02-11 19:21:41

标签: c# visual-studio resharper code-analysis fxcop

我正在使用由第三方程序集公开的枚举,例如,

public enum APIEnum
{
  Val1,
  Val2
}

。但是,许多这些值会导致我的应用程序中的行为不正确。我想在代码中使用其中一个“坏”枚举值时生成编译器警告,例如

APIEnum usedVal = APIEnum.Val2;

Compiler Warning: APIEnum.Val2 causes incorrect behavior.

我的最终目标是生成一个必须有意识的警告#pragma'd如果使用了错误的值(占整个案例的2%)。否则,会发出警告,因为我们将警告设置为错误,这会导致编译中断,直到修复或#pragma'd。

我查看了使用Obsolete属性解决此问题的线程herehere,但我担心Obsolete会引起混淆,因为该值并非真的过时。

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

3 个答案:

答案 0 :(得分:2)

您可以为此创建自定义代码分析(FxCop)规则,或者确实滚动您自己的Resharper规则。自定义代码分析规则应该相对简单check out my rule which checks whether a regex compiles or not,它会查找RegexOptions枚举的所有用法。您应该可以从那里构建自己的自定义规则。

自定义代码分析规则的常用网站:

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

使用VisitAssignment语句,然后使用assignment.Target.Type.FullName获取基础枚举类型。一定要检查Target.Type是否为null,委托可以有一个null类型。

Introspector showing Enum Type

Methodcall也会看到Enum:

Introspector showing Assignment and Methodcall

答案 1 :(得分: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 :(得分: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允许build-time inspection of Resharper rules开箱即用,因此我们至少可以配置我们的CI服务器来查找和报告使用Resharper语法未被抑制的枚举的使用。