代码合同+代码分析
我想在我的代码库中开始使用代码约定 。
我已经使用了代码分析,启用了所有规则,并且目标是零警告。
但是,当使用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类
要解决此问题,需要执行以下步骤:
- 在代码分析中禁用CA1062以消除代码分析中的警告。 目前无法使代码分析理解
Contract.Requires
。 - 在项目的“代码约定”窗格中启用“执行静态合同检查”。
- 启用“隐式非空义务”
- 将警告级别设置为“hi”(重要的是,这就是我所缺少的!)
步骤1取消CA警告,步骤2到4启用代码合同中的警告,该警告至少相当于。