我想在我的代码库中开始使用Code Contracts。代码合同+代码分析
我已经使用代码分析,并启用了所有规则,并且实现了零警告的目标。
然而,在使用Contract.Requires(parameter != null)
当我从代码分析,即CA1062得到一个警告:
CA1062:Microsoft.Design:在外部可见的方法“富”,用它之前验证参数“参数”。
这很不幸,我不想禁用该规则,因为我觉得它很有用。但我也不想压制它的每一个错误发生。
有没有解决方案?
我想在我的代码库中开始使用Code Contracts。代码合同+代码分析
我已经使用代码分析,并启用了所有规则,并且实现了零警告的目标。
然而,在使用Contract.Requires(parameter != null)
当我从代码分析,即CA1062得到一个警告:
CA1062:Microsoft.Design:在外部可见的方法“富”,用它之前验证参数“参数”。
这很不幸,我不想禁用该规则,因为我觉得它很有用。但我也不想压制它的每一个错误发生。
有没有解决方案?
从框架的版本4.5.2(甚至可能是4.5)开始,可以告诉代码分析代码合同执行的合同。首先创建下面的扩展方法和标记属性
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 {}
现在转换您进入空测试,以以下格式:
/// <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]);
}
方法名ContractedNotNull和编译开关RUNTIME_NULL_CHECKS能当然可以改为任何适合你的命名风格的东西。
Here is the original blog通知我这种技术,我稍微细化;非常感谢Terje Sandstrom发表他的研究成果。
波多黎各苏特通过使用附加属性在此here膨胀,导致调试器和内衬更聪明也:
为了解决这个问题,需要按以下步骤进行:
Contract.Requires
。第1步摆脱了CA警告,步骤2至4从代码合同中启用至少等效的警告。
Re#1:CA1062可以全局禁用还是仅通过单独禁止? – Keith
@Keith:您可以在项目属性的代码分析部分禁用它。 –
@DanielHilgarth:截至框架V4.5.2,您可以直接通知代码分析代码合同执行。 –
是否启用@DanielHilgarth代码合同静态验证?这可以在项目属性的代码合同选项卡中找到(启用“执行静态合同检查”)。更多详细信息可以在[代码合同文档](http://research.microsoft.com/en-us/projects/contracts/userdoc.pdf)中找到 – Mightymuke