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,到构造函数?
那么我为什么要抛出自己的异常?
答案 0 :(得分:4)
原因很简单 - 它使调试更容易。
对于需要非null参数的任何给定方法(这是更复杂的方法更真实),调试异常场景的人可以更容易地看到来自SendMail
的显式异常, “嘿,'来自'是空的;我需要它不是,”而不是在SendMail
内进行一些方法调用(或者甚至是其中的一些嵌套方法调用)抛出一个NullReferenceException(最终是如果所讨论的方法都没有执行空检查会发生什么。)
然后,你有一个场景 - 在6个月后 - 你决定SendMail
需要做别的事情;例如(作为一个简单的例子)在数据库中设置某种审计标志。现在,如果您只是让方法失败,那么您将拥有一个无效的标志(或者您可能会这样做,具体取决于方法中的内容顺序)。更好地说“实际上,如果我的参数无效,只是立即失败”,而不是让方法继续进行并产生潜在的副作用。
答案 1 :(得分:1)
一般来说,我认为抛出自己的异常是合理的,因为你可以提供比你正在调用的函数更多的相关信息(要么在代码中处理更具体的异常,要么返回更好的错误消息给用户)。
在这种情况下,您似乎不会添加Send()
无法提供的任何信息。
答案 2 :(得分:1)
smtp.SendMail将抛出InvalidOperationException(在系统命名空间中)
在这里你抛出一个更合适的异常类型,从类型类型中它更容易理解并捕获异常。 InvalidOperationException是一个非常通用的类。通过抛出自己的异常,代码更具可读性,即使您稍后更改方法,也可以处理相同的异常,例如使用另一个mailclient。
答案 3 :(得分:0)
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")
;几个月后,这可以简化你的生活。