Ser*_*uss 33 .net c# error-handling exception
我有时会遇到需要捕获异常的情况,如果它被抛出但从不对它做任何事情.换句话说,可能会发生异常,但如果发生异常则无关紧要.
我最近阅读了这篇关于类似内容的文章:http://c2.com/cgi/wiki?EmptyCatchClause
这个人谈论的评论如何
// should never occur
Run Code Online (Sandbox Code Playgroud)
是代码气味,不应该出现在代码中.然后他们去解释评论如何
// don't care if it happens
Run Code Online (Sandbox Code Playgroud)
完全不同,我自己遇到这样的情况.例如,在发送电子邮件时,我会执行与此类似的操作:
var addressCollection = new MailAddressCollection();
foreach (string address in addresses)
{
try
{
addressCollection.Add(address);
}
catch (Exception)
{
// Do nothing - if an invalid email occurs continue and try to add the rest
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可能认为这样做是个坏主意,因为您希望返回给用户并解释无法将一条或多条消息发送给收件人.但是,如果它只是一个CC地址怎么办?这不太重要,即使其中一个地址无效(可能只是一个错字),您仍然可能仍然希望发送消息.
所以我使用空挡块是对的还是有一个我不知道的更好的替代方案?
Ale*_*x D 73
如果在发生某种类型的异常时您真的不想做任何事情,那么使用空的catch块是完全正确的.您可以通过仅捕获您期望发生的异常类型以及您知道可以安全忽略的类型来改进您的示例.通过捕获Exception
,您可以隐藏错误并使自己更难调试程序.
关于异常处理需要注意的一件事是:用于表示程序外部错误条件的异常之间存在很大差异,预计至少有时发生错误,以及表示编程错误的异常.第1个示例是一个异常,表示由于连接超时而无法传送电子邮件,或者由于没有磁盘空间而无法保存文件.第二个示例是一个异常,表示您尝试将错误类型的参数传递给方法,或者您尝试访问数组元素超出范围.
对于第二个(编程错误),仅仅"吞下"异常将是一个很大的错误.最好的做法通常是记录堆栈跟踪,然后弹出一条错误消息,告诉用户发生了内部错误,并且他们应该将他们的日志发送回开发人员(即您).或者在开发时,您可能只是将它打印到控制台的堆栈跟踪并使程序崩溃.
对于第一个(外部问题),没有关于"正确"事情的规则.这一切都取决于应用程序的细节.如果要忽略某个条件并继续,请执行此操作.
一般来说:
你正在阅读技术书籍和文章是件好事.这样做你可以学到很多东西.但是请记住,正如你所读到的那样,你会发现许多人的建议说做这样的事情总是错的或总是正确的.这些意见往往与宗教有关.永远不要相信以某种方式做事绝对是"正确的",因为一本书或一篇文章(或对......的回答...... <cough>)告诉过你.每条规则都有例外,撰写这些文章的人不知道您的申请的详细信息.你做.确保你正在阅读的内容有意义,如果没有,请相信自己.
Dan*_*zey 18
一个空的挡块在正确的位置是好的- 虽然从你的样品我会说你应该cetagorically 不使用catch (Exception)
.您应该捕获您期望发生的显式异常.
这样做的原因是,如果你吞下一切,你将吞下你不期望的关键缺陷."我无法发送到此电子邮件地址"和"您的计算机磁盘空间不足"之间存在着天壤之别.如果磁盘空间不足,您不想继续尝试发送下一封10000封电子邮件!
"不应该发生"和"不关心它是否发生"之间的区别在于,如果它"不应该发生"那么,当它确实发生时,你不想静静地吞下它!如果这是一个你从未预料到的情况,你通常会希望你的应用程序崩溃(或至少完全终止并记录发生了什么),以便你可以识别这种不可能的情况.
如果永远不应该抛出异常那么就没有必要抓住它 - 它应该永远不会发生,如果确实如此,你需要了解它.
如果存在可能导致失败的特定方案,那么您应该捕获并测试这些特定方案并在所有其他情况下重新抛出,例如
foreach (string address in addresses)
{
try
{
addressCollection.Add(address);
}
catch (EmailNotSentException ex)
{
if (IsCausedByMissingCcAddress(ex))
{
// Handle this case here e.g. display a warning or just nothing
}
else
{
throw;
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,上面的代码捕获特定的(如果是虚构的)异常而不是捕获Exception
.我可以想到很少的情况,它是合法的捕获Exception
,而不是捕获一些你期望被抛出的特定异常类型.
许多其他答案在可以捕获异常时提供了很好的理由,但是许多类支持不抛出异常的方法.
这些方法通常会Try
在它们前面加上前缀.该函数返回一个布尔值,指示任务是否成功,而不是抛出异常.
string s = "Potato";
int i;
if(int.TryParse(s, out i))
{
//This code is only executed if "s" was parsed succesfully.
aCollectionOfInts.Add(i);
}
Run Code Online (Sandbox Code Playgroud)
如果您在循环中尝试上述函数并将其与Parse + Catch equilvilant进行比较,则TryParse方法将更快.
归档时间: |
|
查看次数: |
24958 次 |
最近记录: |