Domanda

I am using an enum being exposed by a 3rd party assembly, e.g.,

public enum APIEnum
{
  Val1,
  Val2
}

. However, a number of these values cause incorrect behavior in my application. I want to generate a compiler warning if one of these "bad" enum values is used in code, e.g.,

APIEnum usedVal = APIEnum.Val2;

Compiler Warning: APIEnum.Val2 causes incorrect behavior.

My ultimate goal is to generate a warning that must be consciously #pragma'd if a bad value is used (2% of the overall cases). Otherwise, the warning occurs, and since we have Warnings as Errors, that breaks the compile until fixed or #pragma'd.

I've looked at the threads here and here on using the Obsolete attribute to solve this problem, but I fear the Obsolete will cause confusion since the value is not really obsolete.

I've considered the possibility of using a Resharper code analysis plugin to solve the problem, and that is definitely an option. I'm no expert on Resharper or how to best solve the problem via Resharper.

È stato utile?

Soluzione

You can use Structural Search in ReSharper. Go to ReSharper -> Options | Code Inspection -> Custom patterns, click Add Pattern, enter APIEnum.Val2 into the field Search pattern and your error description into Description. Set pattern severity to Show as error. Click Add. That's all. The only downside is if you would have another APIEnum with the same Val2 value in your project, even in the different namespace, then it would also be flagged as error.

You should also turn on ReSharper -> Options | Code Inspection -> Settings | Analyse errors in whole solution to show errors in every file.

Altri suggerimenti

You could create a custom Code Analysis (FxCop) rule for this, or indeed roll your own Resharper rule. A custom Code Analysis rule should be relatively simple, check out my rule which checks whether a regex compiles or not, it finds all uses of the RegexOptions enumeration. You should be able to build your own custom rule from there.

General great sites for custom Code Analysis rules:

If you get stuck while writing your own rule, don't hesitate to share the code so far to ask for more specific help.

Use the VisitAssignment Statement, then use the assignment.Target.Type.FullName to get the underlying enum type. Be sure to check Target.Type to be nor null, delegates can have a null Type.

Introspector showing Enum Type

The Methodcall will also see the Enum:

Introspector showing Assignment and Methodcall

I've prototyped a solution using the FxCop approach, and I don't think FxCop can actually solve it. I tried the following code in a rule:

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);
  }
}

When I trace into the VisitBinaryExpression, I find the Operand1 value to be "1" instead of "APIEnum.Val2". This makes sense in hindsight (FxCop working on MSIL which has replaced the enum names/values with numeric literals); I just wish I'd realized it before I dug into the pain/glory of custom FxCop rules. :)

The other approach I found was using StyleCop to do syntax analysis, but this looks even harder to figure out and less popular than custom FxCop rules.

I'm going to propose the use of Resharper team-specific custom patterns as the way of managing this. I remain concerned about this approach (especially since we'll have the same rules across multiple solutions and teams), but the build machine concern is a lot smaller than I thought. TeamCity allows build-time inspection of Resharper rules out of the box, so we can at least configure our CI server to find and report uses of the enum that haven't been suppressed using Resharper syntax.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top