我刚刚看到一个关于try-catch的问题,哪些人(包括Jon Skeet)认为空catch块是一个非常糟糕的主意?为什么呢?在任何情况下,空接点都不是错误的设计决策吗?
我的意思是,例如,有时你想从某个地方(webservice,数据库)获得一些额外的信息,你真的不关心你是否会得到这个信息。所以你试着获取它,如果发生了什么,没关系,我只会添加一个“catch (Exception ignored){}”,仅此而已
我刚刚看到一个关于try-catch的问题,哪些人(包括Jon Skeet)认为空catch块是一个非常糟糕的主意?为什么呢?在任何情况下,空接点都不是错误的设计决策吗?
我的意思是,例如,有时你想从某个地方(webservice,数据库)获得一些额外的信息,你真的不关心你是否会得到这个信息。所以你试着获取它,如果发生了什么,没关系,我只会添加一个“catch (Exception ignored){}”,仅此而已
当前回答
我不会把事情延伸到说使用空catch块的人是一个糟糕的程序员,不知道他在做什么……
如果需要,我使用空捕捉块。有时我正在使用的库的程序员不知道他在做什么,甚至在没有人需要的情况下抛出异常。
例如,考虑一些http服务器库,如果服务器抛出异常,因为客户端已断开连接,index.html无法发送,我不会太在意。
其他回答
只有在确实出现异常时才应该抛出异常——发生了超出正常范围的事情。一个空的catch块基本上表示“一些不好的事情正在发生,但我只是不在乎”。这是个坏主意。
如果您不想处理异常,就让它向上传播,直到它到达一些可以处理它的代码。如果没有任何东西可以处理异常,则应该关闭应用程序。
在极少数情况下,这样做是合理的。在Python中,你经常会看到这样的结构:
try:
result = foo()
except ValueError:
result = None
所以它可能是OK的(取决于你的应用程序):
result = bar()
if result == None:
try:
result = foo()
except ValueError:
pass # Python pass is equivalent to { } in curly-brace languages
# Now result == None if bar() returned None *and* foo() failed
在最近的一个. net项目中,我必须编写代码来枚举插件dll,以查找实现特定接口的类。相关的代码(在VB中。NET,对不起)是:
For Each dllFile As String In dllFiles
Try
' Try to load the DLL as a .NET Assembly
Dim dll As Assembly = Assembly.LoadFile(dllFile)
' Loop through the classes in the DLL
For Each cls As Type In dll.GetExportedTypes()
' Does this class implement the interface?
If interfaceType.IsAssignableFrom(cls) Then
' ... more code here ...
End If
Next
Catch ex As Exception
' Unable to load the Assembly or enumerate types -- just ignore
End Try
Next
尽管在这种情况下,我承认在某个地方记录失败可能是一种改进。
我认为完全空的catch块是一个坏主意,因为没有办法推断忽略异常是代码的预期行为。在某些情况下,接受异常并返回false或null或其他值并不一定是坏事。.net框架有许多“try”方法都是这样操作的。根据经验,如果应用程序支持日志记录,则添加注释和日志语句。
这可能从来都不是正确的事情,因为您正在默默地传递每个可能的异常。如果有您期望的特定异常,那么您应该测试它,如果它不是您的异常则重新抛出。
try
{
// Do some processing.
}
catch (FileNotFound fnf)
{
HandleFileNotFound(fnf);
}
catch (Exception e)
{
if (!IsGenericButExpected(e))
throw;
}
public bool IsGenericButExpected(Exception exception)
{
var expected = false;
if (exception.Message == "some expected message")
{
// Handle gracefully ... ie. log or something.
expected = true;
}
return expected;
}
如果你不知道在catch block中要做什么,你可以只记录这个异常,但不要让它空着。
try
{
string a = "125";
int b = int.Parse(a);
}
catch (Exception ex)
{
Log.LogError(ex);
}