18

我想知道是否应该抛出异常或调用Contract.Requires<TException>

例如:

public static void Function(String str)
{
    if (str == null) throw new ArgumentNullException("str", "Input string cannot be null.");

    // ...
}

对比

public static void Function(String str)
{
    Contract.Requires<ArgumentNullException>(str != null, "Input string cannot be null.");

    // ...
}

由于Contract.Requires<TException>不需要CONTRACTS_FULL符号,我也可以将其保留在我的发布版本中。

这是我的考虑:

缺点:您不能调用自定义异常类型构造函数的重载版本。根本没有办法将额外的参数传递给构造函数。

Pro:静态工具支持(例如通知调用者违反合同)。

我应该使用哪一个,在什么样的情况下?

4

2 回答 2

8

if-then-throwCodeContract 用户指南中记录的和之间的基本权衡Requires<TException>是如何使用发布位进行构建。

案例1:你只用if-then-throw,没有Requires<TException>。在这种情况下,您无需在 dll/exe 上运行合约工具即可构建发布位。优点是您可以更快地构建,并且没有工具引入错误的风险。第二个优势是团队成员可以选择不使用 CodeContract 工具。缺点是您没有对需求的合同继承,并且您的合同不一定对工具可见(除非您使用EndContract)。您可以使用组装模式指定这种情况:自定义参数验证

案例 2:您决定始终在您的发布位上运行 CodeContract 工具。这使您可以使用Requires<TException>并获得合同的继承,包括接口的检测等。您的合同是干净的并且是工具可识别的。缺点是每个构建代码的人都必须安装 CodeContracts 工具。您可以使用组装模式指定这种情况:合同属性窗格中的标准。

希望这能把事情弄清楚。

于 2013-04-26T22:28:18.080 回答
2

我不确定这两种方法之间是否存在任何惊天动地的差异,但我更喜欢合同的原因有两个……

1) 代码更加简洁,因为您在方法的顶部编写了一条语句,显示了该方法所基于的假设。如果违反假设,您不会因为执行而阻塞代码。

2) 当您编写代码时,您将受益于 Visual Studio 获取代码契约,并提示您将要调用的方法期望什么。这可以帮助您确保发送方法有效参数,而无需跳转到方法定义以检查那里的代码。

一旦代码编译并运行,我认为没有任何显着差异。

希望这可以帮助。

于 2013-03-01T14:40:23.950 回答