抛出异常与Contract.Requires <t>?</t>

时间:2013-02-20 23:08:21

标签: c# exception error-handling code-contracts

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

例如:

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

    // ...
}

VS

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

    // ...
}

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

这是我的考虑因素:

Con:您无法调用自定义异常类型构造函数的重载版本。根本没有办法将其他参数传递给构造函数。

Pro:支持静态工具(例如通知来电者合同违规)。

我应该使用哪一个,以及哪种情况?

2 个答案:

答案 0 :(得分:8)

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

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

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

希望这清楚。

答案 1 :(得分:2)

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

1)代码更整洁,因为您在方法的顶部编写了一个语句,该语句显示了该方法所基于的假设。如果违反了假设,你就不会阻塞代码。

2)在编写代码时,您可以从Visual Studio中获取代码合同,并为您提供有关您要调用的方法的提示。这有助于确保您发送方法有效参数,而无需跳转到方法定义来检查那里的代码。

编译并运行代码后,我认为没有任何重大差异。

希望这有帮助。