Code Contracts + Code Analysis

跟風遠走 提交于 2019-12-03 12:02:36

问题


I think about starting to use Code Contracts in my code base.

I already use Code Analysis with all rules enabled and a goal of zero warnings.

However, when using Contract.Requires(parameter != null) I get a warning from Code Analysis, namely CA1062:

CA1062 : Microsoft.Design : In externally visible method 'Foo', validate parameter 'parameter' before using it.

That's unfortunate, I don't want to disable that rule as I find it useful. But I also don't want to suppress every false occurrence of it.

Is there a solution?


回答1:


As of Version 4.5.2 of the framework (possibly even 4.5) it is possible to tell Code Analysis about the contracts being enforced by Code Contracts. First create the following extension method and marker attribute

  using System;
  using System.Diagnostics;
  using System.Diagnostics.CodeAnalysis;
  using System.Diagnostics.Contracts;

  /// <summary>Extension methods to enhance Code Contracts and integration with Code Analysis.</summary>
  public static class ContractExtensions {
#if RUNTIME_NULL_CHECKS
    /// <summary>Throws <c>ArgumentNullException{name}</c> if <c>value</c> is null.</summary>
    /// <param name="value">Value to be tested.</param>
    /// <param name="name">Name of the parameter being tested, for use in the exception thrown.</param>
    [ContractArgumentValidator]  // Requires Assemble Mode = Custom Parameter Validation
    public static void ContractedNotNull<T>([ValidatedNotNull]this T value, string name) where T : class {
      if (value == null) throw new ArgumentNullException(name);
      Contract.EndContractBlock();
    }
#else
    /// <summary>Throws <c>ContractException{name}</c> if <c>value</c> is null.</summary>
    /// <param name="value">Value to be tested.</param>
    /// <param name="name">Name of the parameter being tested, for use in the exception thrown.</param>
    [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "value")]
    [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "name")]
    [ContractAbbreviator] // Requires Assemble Mode = Standard Contract Requires
    public static void ContractedNotNull<T>([ValidatedNotNull]this T value, string name) where T : class {
      Contract.Requires(value != null,name);
    }
#endif
  }

/// <summary>Decorator for an incoming parameter that is contractually enforced as NotNull.</summary>
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
public sealed class ValidatedNotNullAttribute : global::System.Attribute {}

and now convert your entry null-tests to the following format:

/// <summary>IForEachable2{TItem} implementation</summary>
public   void  ForEach(FastIteratorFunctor<TItem> functor) {
  functor.ContractedNotNull("functor"); // for Code Analysis

  TItem[] array = _array;
  for (int i = 0; i < array.Length; i++)    functor.Invoke(array[i]);
}

The method name ContractedNotNull and the compilation switch RUNTIME_NULL_CHECKS can of course be changed to anything that suits your naming style.

Here is the original blog that informed me of this technique, which I have refined slightly; many thanks to Terje Sandstrom for publishing his research.

Rico Suter expands on this here by using additional attributes so that the debugger and inliner are smarter also:

  • DebuggerStepThroughAttribute class
  • MethodImplAttribute class



回答2:


To solve this problem, the following steps need to be performed:

  1. Disable CA1062 in Code Analysis to get rid of the warning from Code Analysis. There is currently no way to make Code Analysis understand Contract.Requires.
  2. Enable "Perform Static Contract Checking" in the Code Contracts pane of the project.
  3. Enable "Implicit Non-Null Obligations"
  4. Set Warning Level to "hi" (important, that was what I was missing!)

Step 1 gets rid of the CA warning, steps 2 to 4 enable a warning from Code Contracts that's at least equivalent.



来源:https://stackoverflow.com/questions/13273842/code-contracts-code-analysis

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!