Contract.Requires的用法

48

这是我的问题。我非常喜欢通过契约设计来开发库,尤其是可以被其他开发人员使用的库。我刚刚发现了一种新的方法,那就是使用Contract.Requires而不是Exception

public void SomeMethod(string name){
   if(name==null) throw new NullArgumentException("Null values not supported");
} 

我现在有:

public void SomeMethod(string name){
   Contract.Requires(name != null);
}

编辑:我正在使用VS2010的调试模式。

问题:即使namenullContract.Requires也不起作用!

MSDN文档中说:

指定封闭方法或属性的前置条件契约。

但是如果未满足条件,则没有任何说明!

我还注意到其他的Contract.Requires有抛出异常、显示消息等重载,那么Contract.Requires(Boolean)是用来做什么的呢?

编辑 下面的回答强调必须安装插件才能使用完整的Contract API,但那么使用Mono平台的用户该怎么办,想要他们的代码在不同平台上表现相同?


你可能会发现这个链接有用:https://dev59.com/MFjUa4cB1Zd3GeqPTKKj - Matthew Strawbridge
1
谢谢你的建议。由于所有这些麻烦,我认为最好还是坚持以前抛出异常的方式。 - GETah
3个回答

26
你应该执行以下步骤:
  1. 按照nfechner的提示安装Code Contracts插件。
  2. 进入项目属性的“Code Contracts”文件夹。
  3. 勾选“执行运行时合同检查”。
  4. 将“程序集模式”切换为“标准契约要求”。
  5. Contract.Requires<SomeException> 替代你的 Contract.Requires (第一种方法会抛出 System.Diagnostics.ContractException,而第二种方法会抛出你指定的异常,这对公共方法非常重要)。
这是基本设置。如果需要更精确的配置,请参考手册
如果使用Mono,可能Contract类是空的。我没有尝试过,但合同手册的第七章似乎解释了如何提供自己的实现。

1
这些提示很有用。在这种情况下,我宁愿坚持使用异常。MONO有类似的工具吗? - GETah
我不仅对在MONO中使用它感兴趣,而且还寻求从Windows到Linux的可移植性,反之亦然。 - GETah
我不确定它是如何工作的,但我认为你应该尝试实现自定义合同运行时。这应该不是很困难。我期望实现能够轻松移植。如果你这样做,并且你有VS Professional+,那么你将获得编译时合同检查的好处,这是非常有价值的。我建议你试一试。 - Pavel Gatilov
5
Code Contracts插件执行后编译步骤,将重写您程序集中的IL以包括运行时检查。如果您的程序集与Mono兼容,则它将在Windows和Linux上执行Contract.Requires(...)检查。唯一的问题是在Linux上编译代码时,IL重写器不可用。如果您所有的开发都在Windows上进行,则Code Contracts不会以任何方式影响跨平台兼容性。 - Allon Guralnek

11

根据Contract类文档

重要提示

您必须安装Visual Studio插件以执行合同。 Code Contracts Premium Edition 插件允许您在项目属性页上指定代码合同的静态和运行时检查。如果您不启用运行时检查,则像 Contract.Ensures 方法这样的合同将不会在运行时抛出异常,如果违反了合同。Visual Studio插件未随Visual Studio 2010或Windows SDK一起提供。


谢谢您的建议,但这只解决了一个方面的问题。请查看我在问题上的更新。 - GETah

2

在这种情况下,通常最好指定您已经完成了哪些操作。

例如,在原始消息中,您没有提到是否安装了VS插件,也没有提到您是否在项目属性下启用了它,或者您实际上是在调试还是发布模式下运行等。

关于 Contract.Requires vs Contract.Requires<Exception>

Contract.Requires 是推荐的方法。 根据手册

如果您的代码必须在特定前提条件失败时抛出特定异常,则可以使用下面的通用重载形式。(在将此形式提交到您的代码之前,请阅读第5.1节。您不能在所有构建上运行合同工具而不使用 Requires < Exn <Exn>>。如果这样做,您将在每次运行时都会发生运行时故障。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接