C# 中的“按合同设计”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/260817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
'Design By Contract' in C#
提问by IAmCodeMonkey
I wanted to try a little design by contract in my latest C# application and wanted to have syntax akin to:
我想在我最新的 C# 应用程序中尝试一些契约式设计,并希望使用类似于以下内容的语法:
public string Foo()
{
set {
Assert.IsNotNull(value);
Assert.IsTrue(value.Contains("bar"));
_foo = value;
}
}
I know I can get static methods like this from a unit test framework, but I wanted to know if something like this was already built-in to the language or if there was already some kind of framework floating around. I can write my own Assert functions, just don't want to reinvent the wheel.
我知道我可以从单元测试框架中获得这样的静态方法,但我想知道这样的东西是否已经内置到语言中,或者是否已经存在某种框架。我可以编写自己的断言函数,只是不想重新发明轮子。
采纳答案by Luke Quinane
C# 4.0 Code Contracts
C# 4.0 代码契约
Microsoft has released a library for design by contract in version 4.0 of the .net framework. One of the coolest features of that library is that it also comes with a static analysis tools (similar to FxCop I guess) that leverages the details of the contracts you place on the code.
Microsoft 在 .net 框架的 4.0 版中发布了一个按合同设计的库。该库最酷的功能之一是它还带有一个静态分析工具(我猜类似于 FxCop),可以利用您放置在代码上的合同的详细信息。
Here are some Microsoft resources:
以下是一些 Microsoft 资源:
Here are some other resources:
以下是一些其他资源:
回答by mmiika
回答by FlySwat
Aside from using an external library, you have a simple assert in System.Diagnostics:
除了使用外部库之外,您在 System.Diagnostics 中有一个简单的断言:
using System.Diagnostics
Debug.Assert(value != null);
Debug.Assert(value == true);
Not very useful, I know.
不是很有用,我知道。
回答by Jim Burger
Spec#is a popular microsoft research projectthat allows for some DBC constructs, like checking post and pre conditions. For example a binary search can be implemented with pre and post conditions along with loop invariants. This example and more:
Spec#是一个流行的微软研究项目,它允许一些 DBC 结构,比如检查后置和前置条件。例如,可以使用前置和后置条件以及循环不变量来实现二分查找。这个例子和更多:
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.
}
Note that using the Spec# language yields compile time checkingfor DBC constructs, which to me, is the best way to take advantage of DBC. Often, relying on runtime assertions becomes a headache in production and people generally elect to use exceptionsinstead.
请注意,使用 Spec# 语言会产生DBC 构造的编译时检查,对我来说,这是利用 DBC 的最佳方式。通常,在生产环境中依赖运行时断言会让人头疼,人们通常会选择使用异常来代替。
There are other languagesthat embrace DBC concepts as first class constructs, namely Eiffelwhich is also available for the .NET platform.
回答by cfeduke
You may want to check out nVentive Umbrella:
您可能想查看nVentive Umbrella:
using System;
using nVentive.Umbrella.Validation;
using nVentive.Umbrella.Extensions;
namespace Namespace
{
public static class StringValidationExtensionPoint
{
public static string Contains(this ValidationExtensionPoint<string> vep, string value)
{
if (vep.ExtendedValue.IndexOf(value, StringComparison.InvariantCultureIgnoreCase) == -1)
throw new ArgumentException(String.Format("Must contain '{0}'.", value));
return vep.ExtendedValue;
}
}
class Class
{
private string _foo;
public string Foo
{
set
{
_foo = value.Validation()
.NotNull("Foo")
.Validation()
.Contains("bar");
}
}
}
}
I wish the Validation extensions were builders so you could do _foo = value.Validation().NotNull("Foo").Contains("bar").Value;
but it is what it is (fortunately its open source so making it a builder is a trivial change).
我希望验证扩展是构建器,所以你可以做,_foo = value.Validation().NotNull("Foo").Contains("bar").Value;
但它就是它(幸运的是它是开源的,所以使它成为一个构建器是一个微不足道的改变)。
And as an alternative solution you could consider domain validation.
作为替代解决方案,您可以考虑域验证。
Finally the new M languages, as part of Oslo, support restrictions on their extents and fields which translate both to T-SQL validation and a CLR class with functioning validation tests (though Oslo is a long time off from release).
最后,作为 Oslo 的一部分,新的 M 语言支持对其范围和字段的限制,这些限制可以转换为 T-SQL 验证和具有功能验证测试的 CLR 类(尽管 Oslo 离发布还有很长时间)。
回答by Hamish Smith
Looking over the code for Moq I saw that they use a class called 'Guard' that provides static methods for checking pre and post conditions. I thought that was neat and very clear. It expresses what I'd be thinking about when implementing design by contract checks in my code.
查看 Moq 的代码,我看到他们使用一个名为“Guard”的类,该类提供用于检查前后条件的静态方法。我认为这很整洁,很清楚。它表达了我在代码中通过契约检查实现设计时的想法。
e.g.
例如
public void Foo(Bar param)
{
Guard.ArgumentNotNull(param);
}
I thought it was a neat way to express design by contract checks.
我认为这是通过合同检查来表达设计的一种巧妙方式。
回答by Liang Wu
You can use a Design By Contract implementation from sharp-architecture. Here is the link: http://code.google.com/p/sharp-architecture/
您可以使用sharp-architecture 中的Design By Contract 实现。这是链接:http: //code.google.com/p/sharp-architecture/
Regards,
问候,
Liang
梁
回答by plaureano
Try LinFu's DesignByContract Library:
试试 LinFu 的 DesignByContract 库:
回答by Tomasz Modelski
For my current project (february 2010, VS 2008) I've choose http://lightcontracts.codeplex.com/
对于我当前的项目(2010 年 2 月,VS 2008),我选择了http://lightcontracts.codeplex.com/
Simple, it's just runtime validation, without any weird complexity, you don't need to derive from some 'strange' base classes, no AOP, VS integration which won't work on some developer workstations, etc.
简单,它只是运行时验证,没有任何奇怪的复杂性,您不需要从一些“奇怪的”基类派生,没有 AOP,VS 集成在某些开发人员工作站上不起作用,等等。
Simplicity over complexity.
简单胜过复杂。
回答by ligaoren
There has an answer in .net Fx 4.0:
.net Fx 4.0 中有一个答案:
System.Diagnostics.Contracts
系统诊断合同
http://msdn.microsoft.com/en-us/library/dd264808.aspx
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);