- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我目前正在研究代码契约,我不完全确定契约类的静态方法是否强大到足以与条件的数学符号竞争。
假设我们有一个简单的阶乘方法
int Factorial(int n);
我要表达以下条件:
Precondition:
n >= 0
Postconditions:
Factorial(n) = 1, in case n = 0
Factorial(n) = n*(n-1)*...*1, in case n > 0
这些条件以简洁明了的方式清楚地指定了 Factorial 的行为。我的问题是,它们是否可以通过代码契约来表达。
先决条件很简单:
Contract.Requires(n >= 0)
条件发布条件可以使用
表示if(n==0)
Contract.Ensures(Contract.Result<int>() == 1);
if(n > 0)
...
但我不喜欢这里需要“if”语句的方式,因为它使前置条件和后置条件的简单列表更难阅读。我希望我们能有类似的东西
Contract.Ensures(...).InCase(...);
最后但并非最不重要的是,我不知道如何表达这个,这是关于数学的常见符号:
n*(n-1)*...*1
我猜我需要某种循环,但这会复制整个实现。有什么聪明的方法来表达这样的符号吗?
提前谢谢你。
最佳答案
您正在寻找的是单元测试,而不是代码契约。
通常,像if n=0, then f(n) = 1
和if n=3, then f(n) = 6
这样的检查是测试用例应表示为单元测试。
在您的情况下,我认为合适的后置条件类似于“结果总是 >= 1”。仅此而已。
假设您的阶乘类看起来像这样:
public class Factorial
{
public int Compute(int n)
{
if (n == 0)
return 1;
return n * Compute(n - 1);
}
}
用 NUnit Framework 编写的合适的单元测试会是:
[TestFixture]
public class FactorialTests
{
[TestCase(0, 1)]
[TestCase(1, 1)]
[TestCase(2, 2)]
[TestCase(7, 5040)]
[TestCase(10, 3628800)]
public void Compute_ReturnsCorrectResult(int n, int expectedResult)
{
var sut = new Factorial();
Assert.AreEqual(expectedResult, sut.Compute(n));
}
}
更新(评论后)
Stating result >= 1 does not fully specify the algorithm.
我不认为代码契约的工作是详细指定算法。算法由方法指定。
如果代码契约是一个复杂的逻辑片段,就像方法本身一样,那么我想我们需要一个代码契约来验证代码契约是否执行了正确的检查。这显然会导致无限递归。
I didn't expect
n*(n-1)*...*1
to be accepted by the compiler. But some generic range operator in a LINQ-flavoured way would surely be a gread addition, e.g. From(n).To(1).Product() or From(n).To(m).Sum()
如果存在这样一种表达阶乘的形式(很可能存在),您当然可以在您的代码中使用它,而不是在代码契约中使用它。
更新 2
为了好玩,我找到了一种计算阶乘的 LINQ 方法:
Enumerable.Range(1, n == 0 ? 1 : n).Aggregate((a, i) => a * i);
关于c# - 代码契约(Contract) : How to express these conditions?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13469379/
我目前正在阅读以了解有关按契约(Contract)设计/代码契约(Contract)的更多信息。 据我所知,就是写契约(Invariants,Pre and Post conditions)来确保代码
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 9年前关闭。 Improve this q
我正在处理 spring cloud contract 并且有一个用例,我希望在缺少一些查询参数时响应为 BAD_REQUEST,而在所有必需查询参数都存在时响应为 OK。为了实现这一点,我有不同的契
按契约(Contract)设计的最佳实践是什么? 在大学里,我通过契约(Contract)范式学习了设计 (在OO环境中) 我们已经学习了三种解决问题的方法: 1)全面编程:涵盖其所有可能的异常(ex
从理论上讲,这似乎是避免错误的一个很好的解决方案,但为什么在实践中我们听到的很少呢? 例如,为什么我们不能在 Java 或 .net 上看到对它的更多支持? 最佳答案 我也一直在寻找这个答案。但它似乎
我读到编译器可以在编译时强制执行 dbc。它是怎么做到的? 最佳答案 据我所知,迄今为止最强大的静态DbC语言是Spec# by Microsoft Research .它使用名为 Boogie 的强
我试图让 VS2010 Ultimate with Code Contracts 生成错误而不是警告。 我有这个简单的测试程序: using System.Diagnostics.Contracts;
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
如何关闭对 Linq2Sql 代码的静态检查? 最佳答案 您可以通过使用 [ContractVerification(false)] 标记有问题的类来抑制对静态代码的检查。 如果您生成的类是部分,您可
我正在使用 WCF 制作一个应用程序的原型(prototype),我正在尝试定义一个回调与派生自另一个接口(interface)的接口(interface)签订契约(Contract)。这样做,生成的
我最近在 .Net Rocks 节目 570 ( http://devjourney.com/community/dotnet-rocks-show-570-with-kevin-hazzard/ )
我注意到微软在 .NET 4 中以一种奇怪的方式命名了他们的代码契约(Contract)相关函数。 他们在“require”和“ensure”的末尾添加“s”,所以有Contract.Requires
我对 WCF 比较陌生。但是,我需要创建一个向 Silverlight 和 AJAX 客户端应用程序公开数据的服务。为了实现这一目标,我创建了以下服务作为概念证明: [ServiceContract(
我一直在兜圈子,试图弄清楚这个问题。 我正在尝试选择已结束最近契约(Contract)但仍保留上一份有效契约(Contract)的员工。 例如,一名员工拥有多份契约(Contract)(有些可能是临时
使用合同密钥,有两个函数fetchByKey和lookupByKey,后者允许我处理否定查找。我没有看到针对合同编号执行相同操作的lookup : (Template t) => ContractId
我有一个用于特定 Assets (A、B、...)的合约的 pandas 数据框。每个契约(Contract)都有开始日期、结束日期(包括两者)和日费率(契约(Contract)不能重叠)。我想生成一
我有这个代码: using System; using System.Diagnostics.Contracts; namespace TestCodeContracts { class Pr
我在使用 Flow 时遇到问题,其中给定的已实现 type 通过要求我仅使用在 type 上声明的属性而不是来限制我的对象 API要求我声明所有 type 的属性。 我是 Flow 的新手,所以我可能
我有一个使用 WCF 与后端数据库通信的 Web 应用程序。我已经一切正常,但我想知道将我相当大的服务契约(Contract)分成几个契约(Contract)是否会更好。 就目前而言,服务契约(Con
我想编写单元测试来验证我的方法不接受无效参数。使用 Code Contract 的 Contract.Requires 调用检查参数的有效性。我为什么要测试合约?我认为我的测试是一种方法规范(实际上是
我是一名优秀的程序员,十分优秀!