参数验证,还是让它失败?

时间:2013-09-23 07:38:00

标签: c#

Aprroach 1:

public static void SendMail(string from, string to, string subject, string body)
{
   if(String.IsNullOrWhiteSpace(from))
      throw new ArgumentNullOrWhiteSpaceException("from");

   if(String.IsNullOrWhiteSpace(to))
      throw new ArgumentNullOrWhiteSpaceException("to");

   var msg = new MailMessage(from, to, subject, body) { IsBodyHtml = true };

   using(var smtp = new SmtpClient())
      smtp.Send(msg);
}

方法2:

public static void SendMail(string from, string to, string subject, string body)
{
   var msg = new MailMessage(from, to, subject, body) { IsBodyHtml = true };

   using(var smtp = new SmtpClient())
      smtp.Send(msg);
}

为什么我要验证方法1中的参数,而不是等待MailMessage抛出异常(方法2),告诉我已经传递了空from或{{1} } value,到构造函数?

那么我为什么要抛出自己的异常?

4 个答案:

答案 0 :(得分:4)

原因很简单 - 它使调试更容易。

对于需要非null参数的任何给定方法(这是更复杂的方法更真实),调试异常场景的人可以更容易地看到来自SendMail的显式异常, “嘿,'来自'是空的;我需要它不是,”而不是在SendMail内进行一些方法调用(或者甚至是其中的一些嵌套方法调用)抛出一个NullReferenceException(最终是如果所讨论的方法都没有执行空检查会发生什么。)

然后,你有一个场景 - 在6个月后 - 你决定SendMail需要做别的事情;例如(作为一个简单的例子)在数据库中设置某种审计标志。现在,如果您只是让方法失败,那么您将拥有一个无效的标志(或者您可能会这样做,具体取决于方法中的内容顺序)。更好地说“实际上,如果我的参数无效,只是立即失败”,而不是让方法继续进行并产生潜在的副作用。

答案 1 :(得分:1)

一般来说,我认为抛出自己的异常是合理的,因为你可以提供比你正在调用的函数更多的相关信息(要么在代码中处理更具体的异常,要么返回更好的错误消息给用户)。

在这种情况下,您似乎不会添加Send()无法提供的任何信息。

答案 2 :(得分:1)

smtp.SendMail将抛出InvalidOperationException(在系统命名空间中)

在这里你抛出一个更合适的异常类型,从类型类型中它更容易理解并捕获异常。 InvalidOperationException是一个非常通用的类。通过抛出自己的异常,代码更具可读性,即使您稍后更改方法,也可以处理相同的异常,例如使用另一个mailclient。

答案 3 :(得分:0)

嗯......你确定100%var msg = new MailMessage(from, to, subject, body) { IsBodyHtml = true };

会抛出这些例外吗?方法2是 未定义的行为。该如何进行单元测试?

SendMail(“”,“”,“”)做什么? extacly?从第二种方法来看并不清楚。

您可以添加评论。但为什么?那不是clean code

arroach 1清楚地定义了函数失败的位置。以及如何处理失败。你的代码应该清楚做什么,而不是评论。

P.S。

抛出新ArgumentNullOrWhiteSpaceException("from");被抛入您的SendMail函数,最接近问题的来源。

如果你使用方法2,只有上帝知道你的召唤中有多深,它会被抓住。

你也可以通过编写类似的东西来改善这一点:

ArgumentNullOrWhiteSpaceException("from - this is usually caused if poo is not bared by poo in goo");几个月后,这可以简化你的生活。