自定义异常有什么用途?

8

我不知道自定义异常能做什么,内置异常不能做什么。这似乎是一个天真的问题,但我确实对此一无所知。你怎么看?

7个回答

11
不同类型的异常出现是为了让你能够使用处理程序仅捕获你想要的异常,让其他异常继续向上传递。因此,你可以通过异常类型安排捕获某些偶尔出现的情况的异常。

实际上,你可能根本不需要经常创建自己的异常。但如果你需要,那么这是因为你需要能够抛出和捕获比可用的异常类型更具体的异常类型,并且可能附带附加信息。


2
顺便提一下:如果您想将更多信息附加到现有的异常,也可以使用其上的 (鲜为人知的) .Data 属性 (请参阅 http://blog.abodit.com/2010/03/using-exception-data-to-add-additional-information-to-an-exception/)。 - Ian Mercer

8

如果符合以下情况之一,创建自定义异常是有用的:

  • 没有内置的异常表达您拥有的错误类型。
  • 您只想捕获特定类型的异常,而不是来自框架的异常。

但通常,如果框架中已经存在可以使用的异常,则最好使用它,而不是为相同的错误创建自己的异常。


6

您可以使用它来实现与应用程序相关的特殊错误处理。假设您构建了一个香蕉应用程序,那么您可以拥有一个OutOfBananasException。如果您的应用程序缺乏香蕉,您可以抛出异常,并在稍后使用特殊错误处理捕获它。

try
{
    EatBananas();
}
catch(OutOfBananasException oobe)
{
    GetMoreBananas();
}
catch(Exception e)
{
    TellUserAndAbort();
}
编辑:
使用自己的异常而不是内置的异常的原因是为了让每个阅读您代码或使用您库的人清楚地知道发生了什么类型的错误。只有在找不到合适的内置异常时才应创建自己的异常。
编辑2:
您可以使用自己的异常做一些内置异常无法实现的事情,例如添加描述错误条件的属性,供错误处理程序使用。如果您有与客户相关的异常,您的异常可以具有客户姓名和客户ID等属性,从而使错误处理程序能够向用户显示信息丰富的错误消息。

2
今天早上我坐下来吃麦片时,我抛出了这个异常!呵呵 - Andrew Barber
我喜欢你使用“香蕉”这个例子的方式,^_^。 - Nam G VU
太好了,现在我饿了。99%的情况下,我自己创建的异常类最终都会被我删除,因为它们没有用处。在上面的例子中,我可能最终会让eatBananas()返回一个布尔值表示成功,而不是抛出异常。当然,如果有三种可能的响应呢... - Tony Ennis
我也是,Tony;我想不起来我曾经真正使用过自定义异常类。但我不知道,ArgumentNullException似乎并不能很好地替代OutOfBananasException! - Andrew Barber

3

在.NET中,只有很少的一些例外情况被特殊处理,比如ThreadAbortException,它通常不能被捕获、处理和忽略。

除此之外,异常类型只是异常类型。你可以像使用框架中定义的异常一样使用自己的异常。


3

3
内置异常的一个烦恼是没有明确区分以下三种情况的异常:
  1. 操作失败,但重试可能会成功;系统状态与尝试操作之前相同。
  2. 操作失败,重试不太可能有帮助;尽管如此,系统状态与尝试操作之前相同;
  3. 某个操作失败,可能会潜在地损坏其他内容。
当捕获异常时,根据捕获位置重新抛出其中一种自定义异常(以上述含义定义)。重新抛出异常时,将原始异常作为InnerException参数传递。
顺便说一句,可以定义通用异常。我不太确定这样做的利弊,并且我从未见过其他人这样做。例如,可以定义一个继承自(自定义)TransientFaultException的TransientFaultException(of T);捕获TimeoutException的应用程序可以将其重新抛出为TransientFaultException(of TimeOutException),并将其作为TransientFaultException(of TimeoutException)或TransientFaultException捕获。不幸的是,必须知道要创建正确的通用类型的异常类型。如果捕获异常并将其传递给TransientFaultException的工厂方法,则新异常的类型将是TransientFaultException(of Exception),而不管最初抛出的异常类型是什么。

2

自定义异常允许您做两件事:

  1. 在异常中捕获自定义类型的数据
  2. 捕获自定义异常发生

只有在没有内置异常以便进行必要处理时才应创建自定义异常。

例如,在我们的应用程序中,当数据层遇到错误时(并将特定的DBMS异常作为内部异常包含在其中),我们会抛出。

我们还有——当我们希望返回一个单一结果但没有结果时,以及——当我们期望返回一个单一结果但得到多个结果时。这使我们能够捕获不同的问题并根据情况对其采取行动。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接