【问题标题】:How to know when to use an existing Exception or write a custom Exception?如何知道何时使用现有异常或编写自定义异常?
【发布时间】:2009-06-10 13:55:47
【问题描述】:

感谢this question 的输入,我决定让我的 Create() 方法抛出异常,正如 Jon Skeet 所说,您不必到处处理它们,并且可以让它们冒泡,似乎是大型应用程序的最佳方法。

所以现在我用这段代码创建我的类的实例:

try
{
    SmartForms smartForms = SmartForms.Create("ball");
    smartForms.Show();
}
catch (CannotInstantiateException ex)
{
    Console.WriteLine("Item could not be instantiated: {0}", ex.Message);
}

自定义异常:

using System;

namespace TestFactory234.Exceptions
{
    class CannotInstantiateException : Exception
    {

    }
}

我如何知道要使用哪个 Exception 类?

在上面的例子中,我创建了自己的异常,因为我不知道从哪里获得“所有系统异常”的列表,或者是否有一个“无法实例化对象”或者它是否有使用它的其他一些含义等。选择异常类型对我来说似乎是一个任意过程,所以创建我自己的似乎是最好的主意。

还是我错过了一些关于异常的东西?决定使用哪种异常类型涉及哪些其他影响?

【问题讨论】:

    标签: c# exception custom-exceptions


    【解决方案1】:

    如果您无法创建对象的原因是 Create 的参数无效,您可能应该抛出 ArgumentException。但是,如果您真的希望能够将这种异常与其他人分开处理,您总是可以创建我们自己的派生自 ArgumentException 的类。 (你确定要吗?)

    【讨论】:

    • 但我看不出使用 ArgumentException 能给我带来什么附加值,例如当我查看这个 MSDN 示例 msdn.microsoft.com/en-us/library/system.argumentexception.aspx 时,您也可以创建一个名为“MyException”或“JimsException”的异常,为什么是“ArgumentException”。这只是一个名字,所以看起来很随意。 ArgumentException 还能给我什么,例如PathTooLongException 没有? msdn.microsoft.com/en-us/library/…,他们似乎都只是回了一条消息,除了他们只是好听的名字,或者他们还有什么?
    • 它比其他任何东西都更具描述性 - 基本上它只是对异常进行分类。这确实意味着您可以捕获 ArgumentException 并获取此异常和类似异常,但这在实践中不太可能发生。
    • 我实际上很少捕获 ArgumentException,除非它是“预期的”。我把它当作一个断言。
    【解决方案2】:

    Why Create Custom Exceptions? 非常详细地解释了为什么以及何时使用自定义异常。

    【讨论】:

    • 这很接近重复。
    • 更好的是,如果他从骗子那里得到答案,我们就不需要这个 Q。
    • 该问题的答案基本上是说“特定异常允许您更好地控制异常处理”这一直是我对异常的自然倾向,所以我不明白为什么我们需要标准化异常,在我看来,它们就像变量名或方法名或类名:这是我的应用程序,所以我可以随心所欲地调用我的异常,所以更准确地说,我在使用 ArgumentException 或使用我自己的 ArgumentException 有什么优势?有什么优势吗?
    • Edward,之所以有内置异常类型,主要是为了标准化抛出的最基本的异常类型,让人们不必重新发明轮子。我认为使用标准与自定义没有任何“优势”,除了您不必创建自己的事实(懒惰作为优势?)
    【解决方案3】:

    当能够捕获并知道发生的特定异常情况可能有用时,创建一个新类型。知道未找到文件而不是通用 IO 异常是否有用?

    【讨论】:

    • 如果我可以更快地打字,我会发布几乎相同的答案:)
    【解决方案4】:

    写了一篇关于这个主题的完整博客文章,您可能会觉得有趣

    总之,不要编写自定义异常类,除非您确实希望有人同时捕获并处理该类型。

    【讨论】:

      【解决方案5】:

      我认为帮助文件中是查找现有异常的好地方...如果您查找Exception 类的帮助,概述页面上应该有一个派生类列表。

      如何决定是创建一个新的(源自Exception),还是从现有的继承,取决于异常的含义。

      正如 Jon 所说,如果您的代码对 Create 方法的参数进行了一些验证,您可能希望从 ArgumentException 派生一个异常(例如,如果指定的 ID 不存在,则可能是 ArgumentNonExistentEntityException虽然有点吃饱了)。

      如果您正在创建的异常在概念上并未从已经存在的异常中“继承”其含义,请为您的库无耻地创建一个新异常。

      【讨论】:

        【解决方案6】:

        您将创建一个自定义异常类型来为错误提供更多上下文信息或含义,否则您将依赖运行时生成的异常类型。例如,像 System.DivideByZero 这样的异常在应用程序的顶部冒泡时可能并不明显。相反,您可以创建一个自定义异常来提供除了上述“除零”错误之外的更多上下文信息。

        有关不同运行时生成的异常的参考,请查看 MSDN 的系统命名空间。这不是一个详尽的列表,因为异常可以由本机代码生成,也可以由第三方库生成。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-06-08
          • 2015-05-26
          • 1970-01-01
          • 1970-01-01
          • 2019-06-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多