什么是例外以及为什么" throw"他们?

时间:2017-04-12 21:44:44

标签: c# exception

我已经在StackOverflow上阅读了很多网站和其他回复,但我仍然没有意识到异常处理的重要性以及为什么我们会抛出"他们。

对于这篇文章,我对异常的理解最好描述为:

  

"异常是在执行程序期间出现的问题。 C#异常是对程序运行时出现的异常情况的响应..." https://www.tutorialspoint.com/csharp/csharp_exception_handling.htm

处理异常时,我经常会看到以下代码snipets:

try 
{
    // Do something that causes an Exception
}
catch (Exception)
{
    // Could have error logging here
    throw;
}

如果您没有执行任何错误记录,为什么要使用" try / catch"和"扔"声明?无论我是否尝试/ catch,代码仍将抛出异常。我肯定错过了什么。什么"投掷"办?

我在下面列出了基本除以零的情况: https://repl.it/BjgV/24。当您删除" try / catch / throw"你看到相同的结果。

3 个答案:

答案 0 :(得分:1)

"投掷"有时候(在非oop语言中)和#34;提高"错误。

如果我们捕获异常,我们可能希望将其冒充到callstack中更高的某个方法,并且可能在此过程中更多地概括它。因此,我们可能会使用类似的东西:

try { doSomething(); } 
catch (VerySpecificException ex) {
    throw new SomeGenericException(ex);
}

这使我们只能期望更高级别的编程中的泛型异常,同时保持完整的堆栈跟踪和内部异常,以便我们可以看到它来自何处。

投掷它自己(例如在你的例子中),只需将错误推送到下一个调用者,不做任何更改。在您的确切示例中,您可能只是完全省略了try / catch,因为结果将是相同的(异常被推送到下一个块:除非您有一些AOP或编织在那里处理它,但是& #39;我认为有点超出这个答案。

如果没有try / catch块,异常将被推回到callstack中的下一个方法。如果在任何地方没有尝试/捕获块,则说例外是未处理的#34;并且您的应用程序崩溃了。没有任何借口可以处理未处理的例外情况。

答案 1 :(得分:1)

特别关于这部分:

  

如果您没有执行任何错误记录,为什么要使用" try / catch"和"扔"声明?

除了记录异常外,在某些情况下您可能需要:

  • 将异常包装在一个有意义的用户定义的异常中,以引发一些错误。
  • 发布某些资源,以防异常发生,并将其冒充以便在其他地方进行潜在处理。

这只是两个例子。

答案 2 :(得分:1)

要记住的是,不仅可以将捕获的异常用于记录错误,还可以将它们用于处理可能出现的错误。

假设您有某种 Widget 对象,它具有通过构造函数参数初始化的属性:

public class Widget
{
    public string Name;

    Widget(string widgetName)
    {
        if (widgetName != "")
            Name = widgetName;
        else
            throw new ArgumentException("Name must be provided for widget.");
    }
}

在这种情况下,我们希望我们的小部件在实例化时有一个名称 - 我们检查参数以查看它是否为空白,我们抛出一个 ArgumentException 来指示构造函数的一个参数出错,并包含一个有关特定错误的有用信息。

这意味着我们可以在包装器中使用特定于上下文的验证逻辑,而不必将所有内容都塞进我们的基本 Widget 类中:

public Widget ForCaseA (string widgetName) 
{
    Widget w;

    try {
        w = new Widget(widgetname);
    }

    catch (ArgumentException as argEx) // We're specifically catching the subtype of ArgumentExceptions; generic Exceptions or other types of exception wouldn't be caught here and would bubble up out of this try/catch block.
    {
// At this point, we could look at the specific data in the exception object to determine what needs to happen to resolve the exception. Since there's only one argument and it's throwing an ArgumentException, we know it's going to be a problem with a bad widgetName. In this case, we can say 'well, in this specific case, we want to give it a default widget name'.
        w = new Widget("DefaultName");
    }

    return w;
}

按类型捕获异常的方法之一是异常有用的是当您使用继承来创建基于泛型异常类的自己的类型时;例如为小部件提供 WidgetException 。这使您可以捕获特定于您的类/实体的问题(例如小部件的名称),但不必处理超出小部件本身范围的问题。< / p>