Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 抛出异常vs合同需要<;T>;?_C#_Exception_Error Handling_Code Contracts - Fatal编程技术网

C# 抛出异常vs合同需要<;T>;?

C# 抛出异常vs合同需要<;T>;?,c#,exception,error-handling,code-contracts,C#,Exception,Error Handling,Code Contracts,我想知道我是应该抛出异常还是调用 例如: public static void Function(String str) { if (str == null) throw new ArgumentNullException("str", "Input string cannot be null."); // ... } vs publicstaticvoid函数(stringstr) { Contract.Requires不需要CONTRACTS\u FULL符号,我也可以将

我想知道我是应该抛出异常还是调用

例如:

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

    // ...
}
vs

publicstaticvoid函数(stringstr)
{
Contract.Requires不需要
CONTRACTS\u FULL
符号,我也可以将其保存在发布版本中

这是我的考虑:

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

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


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

我不确定这两种方法之间是否有任何惊人的差异,但以下是我喜欢合同的两个原因

1) 代码要整洁得多,因为您在方法的顶部编写了一条语句,其中显示了方法所基于的假设。如果违反了假设,代码的实现不会阻塞代码

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

一旦代码被编译并运行,我不认为有任何显著的区别


希望这能有所帮助。

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

案例1:您只使用
如果然后抛出
,则没有
需要
。在这种情况下,您无需在dll/exe上运行契约工具即可构建发布位。优点是构建速度更快,且该工具不会引入错误。第二个优点是团队成员可以选择不使用代码契约工具。缺点是您没有获得requires的契约继承,并且您的契约不一定对工具可见(除非您使用
EndContract
)。您可以使用汇编模式:自定义参数验证来指定这种情况

案例2:您决定始终在发行版上运行CodeContract工具。这使您可以使用
Requires
,并继承契约,包括接口的插入等。您的契约是干净的,并且工具可识别。缺点是,构建代码的每个人都必须拥有CodeContract已安装工具。可通过在“合同属性”窗格中使用“汇编模式:标准”来指定这种情况


希望这能澄清问题。

如果“重载异常类型构造函数”,会有什么好处?@PeterRitchie我认为这些构造函数的存在是出于同样的原因。我猜是因为它提供了更多的数据/信息。我不理解你关于重载异常类型的问题。另外,你可能误解了Contract.Requires的用法。如果你使用重载,你仍然需要在你发布的位上使用这些工具。它不会如果不使用CodeContract工具重写dll,就无法达到预期效果。希望再增加两个优势。契约。可以使用构建符号轻松地“关闭”要求(当您确定检查通过时)。其次(我怀疑Avrohom躲过了)VS有一个可以启用的静态代码分析引擎,它可以找到(可能)违反合同的调用代码的实例。使用VS2017,有一种使CodeContracts工具工作的方法
public static void Function(String str)
{
    Contract.Requires<ArgumentNullException>(str != null, "Input string cannot be null.");

    // ...
}