C# 空捕获块

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16715664/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 01:45:08  来源:igfitidea点击:

Empty catch blocks

c#.netexceptionerror-handling

提问by Serberuss

I sometimes run into situations where I need to catch an exception if it's ever thrown but never do anything with it. In other words, an exception could occur but it doesn't matter if it does.

我有时会遇到需要捕获异常(如果它曾经被抛出但从不对其进行任何处理)的情况。换句话说,可能会发生异常,但是否发生无关紧要。

I recently read this article about a similar thing: http://c2.com/cgi/wiki?EmptyCatchClause

我最近阅读了这篇关于类似事情的文章:http: //c2.com/cgi/wiki?EmptyCatchClause

This person talks about how the comment of

此人谈论如何评论

// should never occur 

is a code smell and should never appear in code. They then go onto explain how the comment

是一种代码异味,不应出现在代码中。然后他们继续解释评论是如何

// don't care if it happens

is entirely different and I run into situations like this myself. For example, when sending email I do something similar to this:

完全不同,我自己也遇到过这样的情况。例如,在发送电子邮件时,我会执行类似的操作:

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
    }
}

Now, you may think that doing this is a bad idea since you would want to return to the user and explain that one or more messages could not be sent to the recipient. But what if it's just a CC address? That's less important and you may still want to send the message anyway even if one of those addresses was invalid (possibly just a typo).

现在,您可能认为这样做是个坏主意,因为您想返回给用户并解释无法将一条或多条消息发送给收件人。但如果它只是一个 CC 地址呢?这不太重要,即使这些地址之一无效(可能只是拼写错误),您仍然可能希望发送消息。

So am I right to use an empty catch block or is there a better alternative that I'm not aware of?

那么我使用空的 catch 块是否正确,还是有我不知道的更好的选择?

采纳答案by Alex D

You are completely right to use an empty catch block if you really want to do nothing when a certain type of exception occurs. You could improve your example by catching only the types of exceptions which you expectto occur, and which you know are safe to ignore. By catching Exception, you could hide bugs and make it harder for yourself to debug your program.

如果您真的想在发生某种类型的异常时什么都不做,那么使用空的 catch 块是完全正确的。您可以通过仅捕获您希望发生的异常类型以及您知道可以安全忽略的异常类型来改进您的示例。通过捕获Exception,您可以隐藏错误并使自己更难调试程序。

One thing to bear in mind regarding exception handling: there is a big difference between exceptions which are used to signal an error condition external to your program, which is expectedto happen at least sometimes, and exceptions which indicate a programming error. An example of the 1st would be an exception indicating that an e-mail couldn't be delivered because the connection timed out, or a file couldn't be saved because there was no disk space. An example of the 2nd would be an exception indicating that you tried to pass the wrong type of argument to a method, or that you tried to access an array element out of bounds.

关于异常处理要记住的一件事:用于表示程序外部错误条件的异常与指示编程错误的异常之间存在很大差异,该异常预计至少有时会发生。第一个示例是异常,表明由于连接超时而无法传送电子邮件,或者由于没有磁盘空间而无法保存文件。第二种情况的一个例子是异常,表明您试图将错误类型的参数传递给方法,或者您试图越界访问数组元素。

For the 2nd (programming error), it would be a big mistake to just "swallow" the exception. The best thing to do is usually to log a stack trace, and then pop up an error message telling the user that an internal error has happened, and that they should send their logs back to the developers (i.e. you). Or while developing, you might just make it print a stack trace to the console and crash the program.

对于第二个(编程错误),仅仅“吞下”异常将是一个很大的错误。最好的做法通常是记录堆栈跟踪,然后弹出一条错误消息,告诉用户发生了内部错误,他们应该将日志发送回开发人员(即您)。或者在开发过程中,您可能只是让它向控制台打印堆栈跟踪并导致程序崩溃。

For the 1st (external problem), there is no rule about what the "right" thing is to do. It all depends on the details of the application. If you want to ignore a certain condition and continue, then do so.

对于第一个(外部问题),没有关于“正确”的事情是做什么的规则。这一切都取决于应用程序的细节。如果您想忽略某个条件并继续,请这样做。

IN GENERAL:

一般来说:

It's good that you are reading technical books and articles. You can learn a lot from doing so. But please remember, as you read, you will find lots of advice from people saying that doing such-and-such a thing is alwayswrong or alwaysright. Often these opinions border on religion. NEVERbelieve that doing things a certain way is absolutely "right" because a book or article (or an answer on SO... <cough>) told you so. There are exceptions to every rule, and the people writing those articles don't know the details of your application. You do. Make sure that what you are reading makes sense, and if it doesn't, trust yourself.

阅读技术书籍和文章是件好事。你可以从中学到很多东西。但是请记住,当您阅读时,您会发现很多人的建议,他们说做某事总是错误或总是正确的。通常,这些观点与宗教有关。永远不要相信以某种方式做事绝对是“正确的”,因为一本书或文章(或关于 SO...<cough> 的答案)告诉了你。每条规则都有例外,撰写这些文章的人不知道您的应用程序的详细信息。你做。确保您正在阅读的内容有意义,如果没有,请相信自己。

回答by Darren

Using an empty catch block just swallows the Exception, I would always handle it, even if it is reporting back to you that an Exceptionoccurred.

使用空的 catch 块只会吞下异常,我会一直处理它,即使它向你报告Exception发生了。

Also catching the generic Exceptionis bad practice due to the fact it can hide bugs in your application. For example, you may have caught an ArgumentOutOfRangeexception which you did not realize was happening and then swallowed it (I.e. not done anything with it).

捕获泛型Exception也是不好的做法,因为它可以隐藏应用程序中的错误。例如,您可能捕获了一个ArgumentOutOfRange您没有意识到正在发生的异常,然后将其吞下(即没有对它做任何事情)。

回答by Justin

If an exception should never be thrown then there is no point catching it - it should never happens and if it does you need to know about it.

如果永远不应该抛出异常,那么捕获它就没有意义——它永远不应该发生,如果发生了,您需要了解它。

If there are specific scenarios that can cause a failure that you are OK with then you should catch and test for those specific scenarios and rethrow in all other cases, for example

如果有可能导致您可以接受的失败的特定场景,那么您应该捕获并测试这些特定场景并在所有其他情况下重新抛出,例如

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;
        }
    }
}

Note that the above code catches specific (if fictional) exceptions rather than catching Exception. I can think of very few cases where it is legitimate to catch Exceptionas opposed to catching some specific exception type that you are expecting to be thrown.

请注意,上面的代码捕获特定的(如果是虚构的)异常而不是捕获Exception. 我可以想到在极少数情况下捕获是合法的,Exception而不是捕获您期望抛出的某些特定异常类型。

回答by Dan Puzey

An empty catch block is fine in the right place- though from your sample I would say you should cetagorically NOTbe using catch (Exception). You should instead catch the explicit exception that you expect to occur.

一个空的 catch 块在正确的位置很好- 尽管从您的示例中我会说您应该使用catch (Exception). 您应该改为捕获您期望发生的显式异常。

The reason for this is that, if you swallow everything, you will swallow critical defects that you weren't expecting, too. There's a world of difference between "I can't send to this email address" and "your computer is out of disk space." You don't want to keep trying to send the next 10000 emails if you're out of disk space!

这样做的原因是,如果你吞下一切,你也会吞下你没有预料到的严重缺陷。“我无法发送到此电子邮件地址”和“您的计算机磁盘空间不足”之间存在天壤之别。如果磁盘空间不足,您不想继续尝试发送接下来的 10000 封电子邮件!

The difference between "should not happen" and "don't care if it happens" is that, if it "should not happen" then, when it doeshappen, you don't want to swallow it silently! If it's a condition you never expected to occur, you would typically want your application to crash (or at least terminate cleanly and log profusely what's happened) so that you can identify this impossible condition.

之间“不应该发生”和“如果它发生不关心”的不同之处在于,如果“不应该发生”,那么,当它没有发生,你不想默默吞下!如果这是您从未预料到的情况,您通常希望应用程序崩溃(或至少干净地终止并大量记录发生的事情),以便您可以识别这种不可能的情况。

回答by Scott Chamberlain

Many of the other answers give good reasons when it would be ok to catch the exception, however many classes support ways of not throwing the Exception at all.

许多其他答案在可以捕获异常时给出了很好的理由,但是许多类支持根本不抛出异常的方法。

Often these methods will have the prefix Tryin front of them. Instead of throwing a exception the function returns a Boolean indicating if the task succeeded.

通常这些方法Try前面会有前缀。该函数不会抛出异常,而是返回一个布尔值,指示任务是否成功。

A good example of this is Parsevs TryParse

一个很好的例子是Parsevs TryParse

string s = "Potato";
int i;
if(int.TryParse(s, out i))
{
    //This code is only executed if "s" was parsed succesfully.
    aCollectionOfInts.Add(i);
}

If you try the above function in a loop and compare it with its Parse + Catch equilvilant the TryParse method will be much faster.

如果您在循环中尝试上述函数并将其与其 Parse + Catch 均衡器进行比较,TryParse 方法将快得多。