【问题标题】:Code Contracts in C# and null checkingC# 中的代码协定和空值检查
【发布时间】:2011-06-09 09:05:46
【问题描述】:

在我的代码中我经常这样做:

myfunction (parameter p)
{
  if(p == null)
   return;
}

如何用代码合同替换它?

我有兴趣找出是否传入了 null 并通过静态检查来捕获它。

如果在我们的测试期间传入 null,我有兴趣抛出合约异常

对于生产,我想退出该功能。

代码合约可以做到这一点吗?这对代码合约有用吗?

【问题讨论】:

  • 为什么要在使用真实数据运行时有效地关闭安全检查?如果您的代码在生产环境中运行时出现错误,那么停止和中止您正在执行的任何操作不是同样重要(如果不是更重要的话)吗?
  • @Jon Skeet:在最近的一个 .Net Rocks 播客中,他们与 C# 4.0 代码合同的主要设计者之一进行了交谈,他们问了同样的问题。我希望我能像他那样解释清楚,但我怕我会弄错。他提出了一个非常有说服力的案例(当你在运行时检查合同时)为什么代码合同总体上更好。
  • @Neil:我没有反对代码合同......但我也会将它们留在生产中。
  • @Neil:我会让合约保持活动状态,这样如果你传入无效参数,它们就会抛出异常。
  • @Neil:是的,我不会关闭安全检查。这就是为什么我问为什么 OP 关闭它们(只是返回而不是抛出异常)。

标签: c# c#-4.0 code-contracts


【解决方案1】:

在为我们的代码库研究代码合同时偶然发现了这个问题。这里的答案是不完整的。发布此内容以供将来参考。

如何用代码合同替换它?

代码相当简单。用此行替换您的运行时空检查。这将引发System.Diagnostics.Contracts.ContractException 类型的异常(显然无法明确捕获,除非捕获所有异常;它并非设计为在运行时捕获)。

Contract.Requires(p != null);

我有兴趣找出是否传入了 null 并通过静态检查来捕获它。

您可以使用 Microsoft 插件进行 Code Contract 静态分析,found here

如果在我们的测试期间传入 null,我有兴趣抛出合约异常

从上面使用以下内容:

Contract.Requires(p != null);

或者,如果您想抛出不同的异常(例如ArgumentNullException),您可以执行以下操作:

Contract.Requires<ArgumentNullException>(p != null, "Hey developer, p is null! That's a bug!");

但是,这需要 Code Contract plugin 中包含的 Code Contracts Binary Rewriter。

对于生产,我想退出该功能。

据我了解,在发布模式下构建项目将禁用代码合同检查(尽管您可以在项目属性中覆盖它)。所以是的,你可以这样做。

代码合约可以做到这一点吗?这对代码合约有用吗?

简短回答 - 是的。

【讨论】:

    【解决方案2】:

    herehere 这些帖子有很多不错的选择。

    编辑:我第一次误读了您的帖子,以为您在抛出 ArgumentNullException 或其他内容,直到我看到 Jon Skeet 的评论。我肯定会建议至少使用链接问题中提供的众多方法中的一种。

    在此处复制 John Feminella 的答案之一:

    [Pure]
    public static double GetDistance(Point p1, Point p2)
    {
        CodeContract.RequiresAlways(p1 != null);
        CodeContract.RequiresAlways(p2 != null); 
        // ...
    }
    

    【讨论】:

    • 没有 CodeContract.RequiresAlways() - 至少我在 VS2013 C# 中没有看到这样的东西
    • 现在已经过时了,但仍然记录在代码contracts user guide
    【解决方案3】:

    这个的语法是:

    Contract.Requires(p != null);
    

    这需要在方法的顶部。所有Contract.Requires(和其他合约语句)必须在方法中的所有其他语句之前。

    【讨论】:

      猜你喜欢
      • 2017-04-18
      • 1970-01-01
      • 1970-01-01
      • 2013-02-06
      • 1970-01-01
      • 1970-01-01
      • 2018-01-04
      • 2014-02-24
      • 1970-01-01
      相关资源
      最近更新 更多