当前位置:  开发笔记 > 编程语言 > 正文

C#中的"按合同设计"

如何解决《C#中的"按合同设计"》经验,为你挑选了4个好方法。

我想在我最新的C#应用​​程序中通过契约尝试一点设计,并希望语法类似于:

public string Foo()
{
    set {
        Assert.IsNotNull(value);
        Assert.IsTrue(value.Contains("bar"));
        _foo = value;
    }
}

我知道我可以从单元测试框架中获取这样的静态方法,但是我想知道这样的东西是否已经内置于该语言中,或者是否已经存在某种类型的框架.我可以编写自己的Assert函数,只是不想重新发明轮子.



1> Luke Quinane..:

C#4.0代码合同

Microsoft已经在.net框架的4.0版本中发布了一个按合同设计的库.该库最酷的功能之一是它还带有静态分析工具(类似于我猜的FxCop),它利用了您对代码签订的合同的详细信息.

以下是一些Microsoft资源:

主要的微软研究网站

用户手册

2008年PDC演讲

2009年PDC演讲

以下是其他一些资源:

.NET 4.0的代码契约 - 规范#活跃起来

.NET代码合同和TDD是互补的

代码合同入门 - 第5部分:利用对象不变量

代码合同入门 - 第6部分接口合同


Spec#的问题在于它绑定到IDE.幸运的是我正在使用4.0,因为System.Diagnostics.Contracts正是我正在寻找的*.属性+代码.真棒.这应该是答案.Debug.Assert的?那不是DbC.

2> Jim Burger..:

Spec#是一个流行的微软研究项目,它允许一些DBC结构,比如检查post和pre条件.例如,二进制搜索可以使用前置条件和后置条件以及循环不变量来实现.这个例子还有更多:

 public static int BinarySearch(int[]! a, int key)
    requires forall{int i in (0: a.Length), int j in (i: a.Length); a[i] <= a[j]};
    ensures 0 <= result ==> a[result] == key;
    ensures result < 0 ==> forall{int i in (0: a.Length); a[i] != key};
 {
   int low = 0;
   int high = a.Length - 1;

   while (low <= high)
     invariant high+1 <= a.Length;
     invariant forall{int i in (0: low); a[i] != key};
     invariant forall{int i in (high+1: a.Length); a[i] != key};
   {
     int mid = (low + high) / 2;
     int midVal = a[mid];

     if (midVal < key) {
       low = mid + 1;
     } else if (key < midVal) {
       high = mid - 1;
     } else {
       return mid; // key found
     }
   }
   return -(low + 1);  // key not found.
 }

请注意,使用Spec#语言会产生DBC结构的编译时检查,对我来说,这是利用DBC的最佳方法.通常,依赖于运行时断言会成为生产中的头痛,人们通常会选择使用异常.

还有其他语言将DBC概念作为第一类构造包含在内,即Eiffel也可用于.NET平台.



3> FlySwat..:

除了使用外部库,您在System.Diagnostics中有一个简单的断言:

using System.Diagnostics

Debug.Assert(value != null);
Debug.Assert(value == true);

我知道,不是很有用.


这将在发布版本中编译.

4> ligaoren..:

.net Fx 4.0中有一个答案:

System.Diagnostics.Contracts

http://msdn.microsoft.com/en-us/library/dd264808.aspx

Contract.Requires(newNumber > 0, “Failed contract: negative”);
Contract.Ensures(list.Count == Contract.OldValue(list.Count) + 1);

推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有