代码合同+代码分析

我想在我的代码库中开始使用代码约定 。

我已经使用了代码分析,启用了所有规则,并且目标是零警告。

但是,当使用Contract.Requires(parameter != null)我收到代码分析的警告,即CA1062:

CA1062:Microsoft.Design:在外部可见方法’Foo’中,在使用之前validation参数’parameter’。

这很不幸,我不想禁用该规则,因为我发现它很有用。 但我也不想压制它的每一个错误发生。

有解决方案吗?

从框架的版本4.5.2(甚至可能是4.5)开始,可以告诉代码分析有关代码合同强制执行的合同。 首先创建以下扩展方法和标记属性

  using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; /// Extension methods to enhance Code Contracts and integration with Code Analysis. public static class ContractExtensions { #if RUNTIME_NULL_CHECKS /// Throws ArgumentNullException{name} if value is null. /// Value to be tested. /// Name of the parameter being tested, for use in the exception thrown. [ContractArgumentValidator] // Requires Assemble Mode = Custom Parameter Validation public static void ContractedNotNull([ValidatedNotNull]this T value, string name) where T : class { if (value == null) throw new ArgumentNullException(name); Contract.EndContractBlock(); } #else /// Throws ContractException{name} if value is null. /// Value to be tested. /// Name of the parameter being tested, for use in the exception thrown. [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([ValidatedNotNull]this T value, string name) where T : class { Contract.Requires(value != null,name); } #endif } /// Decorator for an incoming parameter that is contractually enforced as NotNull. [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] public sealed class ValidatedNotNullAttribute : global::System.Attribute {} 

现在将您的条目空值测试转换为以下格式:

 /// IForEachable2{TItem} implementation public void ForEach(FastIteratorFunctor functor) { functor.ContractedNotNull("functor"); // for Code Analysis TItem[] array = _array; for (int i = 0; i < array.Length; i++) functor.Invoke(array[i]); } 

方法名称ContractedNotNull和编译开关RUNTIME_NULL_CHECKS当然可以更改为适合您的命名样式的任何内容。

这是原始的博客告诉我这项技术,我稍微改进了一下; 非常感谢Terje Sandstrom发表他的研究成果。

Rico Suter通过使用其他属性扩展了这一点 ,以便调试器和内联器也更智能:

  • DebuggerStepThroughAttribute类
  • MethodImplAttribute类

要解决此问题,需要执行以下步骤:

  1. 在代码分析中禁用CA1062以消除代码分析中的警告。 目前无法使代码分析理解Contract.Requires
  2. 在项目的“代码约定”窗格中启用“执行静态合同检查”。
  3. 启用“隐式非空义务”
  4. 将警告级别设置为“hi”(重要的是,这就是我所缺少的!)

步骤1取消CA警告,步骤2到4启用代码合同中的警告,该警告至少相当于。