【发布时间】:2013-10-24 19:18:00
【问题描述】:
我对异常没有太多经验,我正在尝试弄清楚如何在现实世界的场景中正确使用异常处理。在 C# 中。
在这个示例中,我有一个顶级函数 LoadModel,它调用许多其他函数(调用其他函数……):
class Core
{
public void LoadModel(string file_name)
{
try
{
// call other functions (that call other functions, …) that may throw exceptions
}
catch (Exception ex)
{
if (ex is ArgumentNullException ||
ex is ArgumentException ||
ex is EncoderFallbackException ||
ex is InvalidOperationException ||
ex is XmlException ||
ex is InvalidDataException ||
ex is IOException)
{
// show error message
}
else
{
// unsupported exception. system may be unstable. let it crash.
throw;
}
}
}
}
我遵守了这条规则:
- 所有函数都使用异常报告错误,即它们不返回 错误代码。它与 .NET 框架中的范例相同。
- 如果您在某个较低级别的函数内部并且发生异常并且它不是 适合在这个地方向用户报告失败,不要捕获异常并让它向上传播调用堆栈。
- 不要使用空 catch 来 在顶层捕获所有异常。它会隐藏你的问题 应用程序可能会破坏它。仅捕获您知道如何处理的异常 恢复。
问题:这是您处理异常的方式吗? IE。我检查我的受保护代码生成了哪些异常(也考虑所有嵌套函数),确定从哪些异常可以安全恢复并将它们放入高级捕获中。我可以从他们的文档中获取 .NET 函数的异常列表,对于我自己的函数,我应该在他们的文档中保留异常列表。而且这个异常列表趋于累积:一个函数可以抛出它自己的异常和它的嵌套函数的异常……。我似乎很容易出错。有人在某个嵌套函数中添加了新异常,而您的顶级 catch 将无法处理它。使用错误代码,您可以执行“if (error != SUCCESS)”之类的操作来捕获所有错误,但您不能使用异常来执行此操作(如果您不想使用空 catch)。
【问题讨论】:
-
通常的风格是为每种异常类型设置几个 catch 语句,而不是一个大的 if 语句。
-
将异常称为“不受支持”会很奇怪。所有异常都应该以一种或另一种方式优雅地处理(或“支持”)。无论是通过记录它并继续前进、抛出错误消息、处理预期的异常和修复问题等等。你应该永远有一个只会让你的程序崩溃的异常。那将被称为错误。
-
当我在一些较低级别的函数中时,我通常会执行 try/catch 并在 catch 中重新抛出异常(抛出 ex;)。这样可以更清楚地知道异常可能引发的位置。
-
@dave 否。
throw ex是绝对错误和不好的做法。它不仅会破坏您的堆栈跟踪,而且还会表明异常的来源是throw ex并且 不是 实际抛出的位置。要正确地重新抛出异常,只需使用throw;Good example here -
谢谢 tnw,你的权利!使用只是扔。但是这样做是一个好习惯,不要让异常跳转到上面的函数不受控制,不是吗?
标签: c# exception-handling