代码契约.net-备选方案

代码契约.net-备选方案,.net,code-contracts,.net,Code Contracts,最近,我开始使用。在我看来,代码契约本身的想法很好,但实现起来却非常令人不快 我不喜欢它的主要原因是: 我只能在我的过程中使用像Contract.Require()这样的方法ContractAbreviators有很多限制(比如,我不能将它们放在单独的程序集中,也不能使用参数),这会降低它们的可用性。没有属性,也没有扩展方法,所以我的代码变得非常冗长。例如,如果我只想检查Dictionary类型的返回值是否不为null,我需要添加一个怪物,例如Contract.sure(Contract.Re

最近,我开始使用。在我看来,代码契约本身的想法很好,但实现起来却非常令人不快

我不喜欢它的主要原因是:

  • 我只能在我的过程中使用像
    Contract.Require()
    这样的方法
    ContractAbreviator
    s有很多限制(比如,我不能将它们放在单独的程序集中,也不能使用参数),这会降低它们的可用性。没有属性,也没有扩展方法,所以我的代码变得非常冗长。例如,如果我只想检查
    Dictionary
    类型的返回值是否不为null,我需要添加一个怪物,例如
    Contract.sure(Contract.Result!=null)
    。它甚至不可读
  • 静态分析器会产生如此多的错误警报,以至于我花更多的时间关闭它,而不是修复实际问题
  • 它非常慢。尽管它有一些缓存,但分析一个小项目也需要几分钟的时间,这使得它对于增量修复毫无用处。只是时间太长了
  • ccrewriter
    中存在错误-它无法处理一半的程序集,并且无法在.net 4.5运行时的.net 4.0程序集中生存
  • 存在运行时/静态检查器二元论。当我刚开始的时候,我认为它就像Debug.Assert一样简单-你只要在你需要的地方添加它们就行了。但事实证明,我需要向静态检查器证明一切,这当然是先进的,但检查器有时很愚蠢,无法解决许多明显的代码构造(如
    while
    )。而且没有仪器可以对分析仪说“我知道我在做什么,忽略这一违反合同的行为”
  • 您无法关联条件。例如,无法向静态分析器解释,如果我选中
    string.NotNullOrEmpty
    这包括
    string!=空
    。或者,如果我有自己的检查文件路径的大过程,我无法向分析器解释它肯定不是空的。
    contractAbreviator
    属性有一点帮助,但所有这些冗长的内容都在那里,它仍然看起来肮脏而愚蠢
  • 代码契约的开发非常缓慢,即使它现在是开源的,但据我所知,代码库处于糟糕的状态

除了代码契约之外,还有什么缺陷更少的高级替代方案吗?

我不知道有什么替代方案,但我也许可以解决您的一些问题。我所在的团队在我们所有的代码(约1000个模块)中使用契约,并在每次签入以及VS中运行静态分析

  • 代码丑陋。我们对(几乎)所有东西都有单独的接口,以及实现这些接口的抽象类,由ContractClass和ContractClassFor属性连接。契约在类的抽象ContractClassFor中,这使得实际的实现代码几乎不受代码契约的约束

  • 静态分析器的缓慢通常是由于没有足够的契约,这迫使分析器做更多的工作来找出契约是否可以被打破

  • 静态检查错误警报。我有过一些,但还没有到成为问题的程度。同样,如果合同太少,静态检查器可能无法及时完成分析

  • 静态分析器的慢度可以使用这些MSBuild选项进行调试,这将显示哪些方法花费的时间最多

    msbuild myproject.sln/p:codecontractstraanalysisoptions=“-show progress-stats=!!-stats slowMethods”

  • 如果您确定某些条件始终有效,那么您可以使用Contract.aspect(condition)来指示静态检查器假设情况就是这样。例如

    契约。假设(mystring!=null&&mystring!=“”)
    或者只是
    契约。假设(!string.IsNullOrEmpty(mystring))

  • 关于Debug.Assert的使用,我认为进行静态检查是一个巨大的优势,而不仅仅是让我的应用程序在客户站点崩溃。这样,我就可以在发布产品之前消除应用程序崩溃的风险。也许我误解了你,但我真的认为你的比较没有意义