c# - 试图理解 C# 中的异常

标签 c# .net exception exception-handling

我并没有真正在我的代码中使用任何 try/catches,但我正在努力打破这个习惯,现在开始使用异常。

我认为在我的应用程序中最重要的地方是读取文件,我现在正在尝试实现它,但我不确定这样做的“最佳实践”。目前我正在做这样的事情:

private void Parse(XDocument xReader)
{
    IEnumerable<XElement> person = xReader.Descendants("Person").Elements();

    foreach (XElement e in person)
        personDic[e.Name.ToString()] = e.Value;

    if (personDic["Name"] == null || personDic["Job"] == null || personDic["HairColor"] == null)
        throw new KeyNotFoundException("Person element not found.");
}

但我不确定这是否正确。我有这个来处理它:

try
{
    personsReader.Read(filename, persons);
}
catch (KeyNotFoundException e)
{
    MessageBox.Show(e.Message);

    return;
}

// Do stuff after reading in the file..

然而,当显示 e.Message 时,它​​只显示通用的 KeyNotFoundException 错误消息,而不是自定义错误消息。此外,我不确定我是否正在正确处理整个“异常处理问题”。我确实在捕获中返回,因为如果文件未成功读取,显然我只想假装用户从未尝试打开文件并让他用另一个文件重试。

我做得对吗?同样,我对使用异常还很陌生,我想确保在继续并将其应用到我的程序的其余部分之前我已经正确理解了它。

此外,为什么人们说不要执行 catch (Exception e)?在这种情况下,我似乎想这样做,因为无论读取文件时发生什么错误,如果有错误,我都想停止读取文件,显示错误消息,然后返回。不总是这样吗?我可以理解不想处理异常 e 如果你想根据异常处理不同的东西,但在这种情况下,我不想只处理基本异常类以防出现任何问题吗?

最佳答案

当您可以处理 条件并做一些有用的事情时,您应该捕获异常。否则你应该让它在调用堆栈中冒泡,也许你上面的人可以处理它。一些应用程序在最外层有未处理的异常处理程序来处理它,但一般来说,除非你知道你有一些有用的方法来处理它,否则就放手吧。

在您的情况下,您正在处理无法读取资源并通知用户的问题。你在处理它。关于通用异常,您可以做的一件事是捕获并重新抛出更好的异常。如果这样做,请确保将根本原因异常包含为内部异常。如果合适,您还可以跟踪或记录详细信息。

throw new MyGoodExceptionType ("Could not read file", e);  // e is caught inner root cause.

现在 UI 显示了一个很好的错误,也许内部根本原因在日志等中......

一些典型的错误:

  • 在通用库方法中处理堆栈深处的异常:请记住,一个通用库函数可能会在许多不同的代码路径中被调用。您可能不知道是否应该处理它以及是否适合处理它。堆栈中较高层的调用者可能有上下文并且知道处理它是否安全。通常这意味着更高层的代码决定处理。在较低层,通常你让它们流动。

  • 吞噬异常:一些代码捕获异常(尤其是在堆栈中较低的部分),然后根本条件就消失了,这使得调试变得令人抓狂。再说一遍,如果你能处理好,那就去做吧。如果没有,就放手吧。

  • 异常应该是异常的:不要使用异常来进行流量控制。例如,如果您正在阅读资源,请不要尝试阅读然后捕获异常并做出决定。相反,调用 ifexists,检查 bool 并在代码中做出决定。当您将调试器设置为中断异常时,这尤其有用。您应该能够干净地运行,如果调试器中断,那应该是一个真正的问题。调试有问题时让调试器不断中断。我个人很少抛出异常,并且总是尽量避免抛出异常。

希望对您有所帮助。

关于c# - 试图理解 C# 中的异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7238402/

相关文章:

.NET 命名空间

.net - XSD : Could not find schema information for the element 的 XML 验证

java - 是否可以覆盖 JUnit 中的预期异常?

language-agnostic - 尽早抛出异常是一种好习惯吗?

c# - Autofac - 注入(inject) UmbracoContext.ContentCache

c# - 从另一个函数调用 RowDataBound

c# - 访问当前系统时区

javascript - 尝试使用 Node JS 设置 API 管理 REST API 身份验证

c# - 使用 .NET 开发新的应用程序?

java - 在 Java 中使用 FTP 并检测断开连接