代码合约 + 代码分析

Posted

技术标签:

【中文标题】代码合约 + 代码分析【英文标题】:Code Contracts + Code Analysis 【发布时间】:2012-10-27 18:03:22 【问题描述】:

我考虑开始在我的代码库中使用Code Contracts。

我已经在启用所有规则并实现零警告目标的情况下使用代码分析。

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

CA1062:Microsoft.Design:在外部可见的方法“Foo”中,在使用之前验证参数“parameter”。

很遗憾,我不想禁用该规则,因为我觉得它很有用。但我也不想压制它的每一个错误发生。

有解决办法吗?

【问题讨论】:

@DanielHilgarth 您是否启用了代码合约静态验证器?这可以在项目属性的代码合同选项卡中找到(启用“执行静态合同检查”)。更多详情可以在Code Contracts Documentation中找到 【参考方案1】:

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

    在代码分析中禁用 CA1062 以消除来自代码分析的警告。目前没有办法让代码分析理解Contract.Requires。 在项目的 Code Contracts 窗格中启用“Perform Static Contract Checking”。 启用“隐式非空义务” 将警告级别设置为“hi”(重要的是,这正是我所缺少的!)

第 1 步消除了 CA 警告,第 2 步到第 4 步启用了来自代码合同的警告,该警告至少是等效的。

【讨论】:

Re #1:CA1062 可以全局禁用还是仅通过个别抑制禁用? @Keith:您可以在项目属性的代码分析部分禁用它。 @DanielHilgarth:从框架 V4.5.2 开始,您可以直接通知代码分析正在执行的代码合同。【参考方案2】:

从框架的 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>ArgumentNullExceptionname</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>ContractExceptionname</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>IForEachable2TItem 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 发表了他的研究。

Rico Suter 通过使用附加属性扩展了这个 here,使调试器和内联器也更智能:

DebuggerStepThroughAttribute class MethodImplAttribute class

【讨论】:

以上是关于代码合约 + 代码分析的主要内容,如果未能解决你的问题,请参考以下文章

EOSIO源码分析 - CDT合约编译过程

[以太坊源代码分析] I.区块和交易,合约和虚拟机

区块链 acala源代码分析之一 evm合约调用evm_contract_call

区块链 | 智能合约Ethereum源代码- 以太坊RPC通信实例和原理代码分析(上)

区块链 moonbeam源代码分析之三 evm合约调用evm_contract_call

区块链智能合约美链攻击分析以及安全库的使用