c# - 什么是异常(exception)?

原文 标签 c# c++ language-agnostic exception exception-handling

我们每天都在谈论异常处理。我们都知道它是在执行遇到一些意外情况时创建的东西。

这里有几个问题:

  • 什么是异常(exception)?它的最低级内存组合是什么?在 .NET 中,我可以将其视为某种异常类型的某个对象实例。在原生世界中,它是由什么构成的?一些数据结构?
  • 如果异常不是由程序员显式抛出的,那么谁创建异常,如以下代码所示?它是某些语言运行时提供的支持的一部分吗?

    SomeException e = new SomeException();
    扔e;
  • 什么是异常工作范式?当某些错误发生时,语言运行时会创建相应数据结构/类型的实例来表示错误的详细信息,这是真的吗?
  • 我们如何在运行时知道所有可能的意外情况,从而创建足够的异常数据结构/类型来表示它们?

  • 感谢您的回复。

    最佳答案

    您的问题的答案很大程度上取决于我们所谈论的语言。

    C 没有异常(exception) 完全没有,尽管有专有语言扩展。
    C++ 有办法“扔”一个 任意对象在您的代码中的任何一点,并将其“捕获”在调用堆栈更高的某个位置。
    C# 有办法“扔”派生自 System.Exception 的对象并且还从堆栈的更高位置“捕获”那些。此外,我认为 .NET 运行时会在每次抛出异常时报告一些问题。

    • What is an exception? What's its most low-level in-memory composition? In .NET, I can think of it as some object instance of some exception type. In the native world, what is it made of? Some data sturcures?


    在 C++ 中,它只是一个任意对象,它像代码中的其他对象一样被创建:
    throw 42;                     // throws an int object
    throw "blah";                 // throws a char[5] object
    throw std::string("arg!");    // throws a std::string object
    throw my_type(42);            // throws a my_type object
    throw std::exception("doh!"); // throws a std::exception object
    

    抛出异常与 catch 的匹配短语与重载函数的匹配非常相似。 (一个很大的区别是流行语是有序的。也就是说,第一个匹配的将“获胜”并捕获对象。但是,重载函数必须始终提供明确的最佳匹配。)

    • Who create the exception if the exception is not thrown explicitly by the programmer as the following code shows? Is it part of the support that certain language runtime provides?


    在 C++ 中,异常几乎只能从代码中抛出。它可以是您自己的代码、其他人的代码、某个库的代码或标准库的代码。但通常必须有一个 throw某处声明。对此有一些异常(exception)(没有双关语),例如 std::bad_allocnew 抛出(这可能是从代码中的 throw 语句中抛出的,但我认为没有必要)和 std::bad_cast ,从 dynamic_cast<> 抛出. (此外,预计明年的下一个标准 C++1x 允许异常以某种方式跨越线程边界,这可能需要标准库实现者找到一种方法将异常存储在一个线程中并从另一个线程重新抛出它。但我'我对此很模糊。)

        SomeException e = new SomeException(); throw e;
    


    在 C++ 中,你可以,但你很少会想要,抛出指针。你要么做
    SomeException e; throw e;
    

    或者
    throw SomeException();
    

    • What is the exception working paradigm? Is it true that when some error happens, an instnace of the corresponding data structure/type is created by the language runtime to represent the details of the error?


    C++ 标准库抛出异常的地方很少,但除此之外,我只能想到上面提到的两个特性(加上 C++1x 中的一个),其中运行时会“自己”抛出异常。

    • How could we know all the possible unexpected situations at runtime and thus create enough exception data structures/types to represent them?


    通常只抛出派生自 std::exception 的类的对象。在 C++ 中,尽管我遇到过使用它们自己的异常类层次结构的代码,而这些层次结构并非 Root 于 std::exception .标准库中异常层次结构的问题在于,它的类是从彼此非虚拟地派生出来的,这使得您自己的异常层次结构无法使用多重继承来掩盖标准库中的异常层次结构。 (就像拥有您自己的 OutOfRange 异常类型,它继承自 std::out_of_range 和您的异常基类 MyException ,它继承自 std::exception 。)

    C++处理异常的方式主要基于以下原则:
  • 以使其不受任何时候抛出的异常影响的方式编写代码。使用 RAII和其他技术来实现这一点。
  • 仅在您可以对其采取措施的地方捕获异常。
  • 仅在异常情况下抛出异常。不要将它们用于控制流。 (C++ 异常的设计目标是让供应商能够实现它们,以便在非异常情况下最小化开销,以异常情况为代价。)
  • 关于c# - 什么是异常(exception)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4085577/

    相关文章:

    c++ - unordered_map.emplace给编译器时间错误?

    C++ cout.endl() 清除缓冲区,cout.flush() 不

    algorithm - 获取二维数组中的相邻元素?

    c# - MVC 通过 AJAX 发送列表

    c# - 我可以在 header 元素中未定义的JavaScript函数上使用WebBrowser.Document.InvokeScript吗?

    c# - Socket.ConnectAsync收到400错误请求,而Socket.Connect获得200正常

    c++ - 在SFINAE中将int缩小为bool,gcc和clang之间的输出不同

    validation - 验证假名输入

    algorithm - 什么是计算机科学中的 NP-complete?

    c# - 参数中具有动态的 Asp.net mvc Action