“合同设计” 在 C# 中
我想在最新的 C# 应用程序中尝试按合同进行一些设计,并希望具有类似于以下内容的语法:
public string Foo()
{
set {
Assert.IsNotNull(value);
Assert.IsTrue(value.Contains("bar"));
_foo = value;
}
}
我知道我可以从单元测试框架中获取这样的静态方法,但我想知道是否已经构建了这样的东西 -或者是否已经存在某种框架。 我可以编写自己的断言函数,只是不想重新发明轮子。
I wanted to try a little design by contract in my latest C# application and wanted to have syntax akin to:
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
Microsoft 在 .net 框架 4.0 版本中发布了一个用于契约设计的库。 该库最酷的功能之一是它还附带了一个静态分析工具(我猜类似于 FxCop),该工具利用您在代码上放置的合约的详细信息。
以下是一些 Microsoft 资源:
以下是一些其他资源:
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.
Here are some Microsoft resources:
Here are some other resources:
Spec# 是一个流行的微软研究项目,允许某些 DBC 构造,例如检查后置条件和先决条件。 例如,可以使用前置条件和后置条件以及循环不变量来实现二分搜索。 此示例及更多内容:
请注意,使用 Spec# 语言会产生编译时检查 em> 对于 DBC 构造,对我来说,这是利用 DBC 的最佳方式。 通常,依赖运行时断言会成为生产中的一个难题,人们通常选择 使用异常来代替。
还有其他语言将DBC概念作为一流的构造,即Eiffel 也可用于 .NET 平台。
Spec# is a popular microsoft research project that 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:
Note that using the Spec# language yields compile time checking for 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 exceptions instead.
There are other languages that embrace DBC concepts as first class constructs, namely Eiffel which is also available for the .NET platform.
除了使用外部库之外,您在 System.Diagnostics 中还有一个简单的断言:
我知道,不是很有用。
Aside from using an external library, you have a simple assert in System.Diagnostics:
Not very useful, I know.
.net Fx 4.0 中有一个答案:
System.Diagnostics.Contracts
http:/ /msdn.microsoft.com/en-us/library/dd264808.aspx
There has an answer in .net Fx 4.0:
System.Diagnostics.Contracts
http://msdn.microsoft.com/en-us/library/dd264808.aspx
查看 Moq 的代码,我发现他们使用名为“Guard”的类提供用于检查前置条件和后置条件的静态方法。 我认为这很简洁而且非常清晰。 它表达了我在代码中通过契约检查实现设计时的想法。
例如,
我认为这是通过合同检查来表达设计的一种巧妙方式。
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.
e.g.
I thought it was a neat way to express design by contract checks.
您可能想查看 nVentive Umbrella:
我希望验证扩展是构建器,这样您就可以执行
_foo = value.Validation().NotNull("Foo").Contains("bar").Value;
但这就是它的本质(幸运的是它是开源的,所以使它成为一个构建器是一个微不足道的改变) 。作为替代解决方案,您可以 考虑域验证。
最后是新的M语言,作为 Oslo 的一部分,支持对其范围和字段的限制,这些限制可转换为 T-SQL 验证和具有功能验证测试的 CLR 类(尽管 Oslo 距离发布还有很长一段时间)。
You may want to check out nVentive Umbrella:
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).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).
对于我当前的项目(2010 年 2 月,VS 2008),我选择 http://lightcontracts.codeplex.com/
简单,它只是运行时验证,没有任何奇怪的复杂性,您不需要从一些“奇怪”的基类派生,没有 AOP,VS 集成在某些开发人员工作站上不起作用等。
简单胜于复杂。
For my current project (february 2010, VS 2008) I've choose 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.
Simplicity over complexity.
最直接的方法,也是 .NET Framework 本身使用的方法,是:
The most straightforward way, and the way used in the .NET Framework itself, is to do:
请注意,我在 C# 中为 DbC 创建了一个非常简单的类,它应该可以在 .NET 6 和我相信的任何 .NET 中工作,它非常简单且有限,但它可以达到使用前置条件、后置条件和断言的目的。
就在这里
,用法可以是类似
or
等
。
Please note that I created an extremely simple class for DbC in C#, it should work in .NET 6, and any .NET I believe, it is very simple and limited, but it can serve the purpose of using preconditions, postconditions and assertions.
Here it is
and the usage can go something like
or
or
etc.