Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对于自定义异常,我们可以做什么?_C#_.net_Exception - Fatal编程技术网

C# 对于自定义异常,我们可以做什么?

C# 对于自定义异常,我们可以做什么?,c#,.net,exception,C#,.net,Exception,我不知道自定义异常可以做什么,内置异常不能做什么。这似乎是一个天真的问题,但我真的不知道。 你认为呢?在.NET中只有少数例外情况是以特殊的方式处理的,例如,它们(通常)不能被捕获、处理和吞咽 除此之外,异常类型只是异常类型。您可以对自己的异常执行与对框架中定义的异常执行几乎相同的操作。在以下情况下,创建自定义异常非常有用: 没有表示错误条件类型的内置异常 您希望只捕获特定类型的异常,而不捕获来自框架的异常 但通常情况下,如果框架中已经存在可以使用的异常,那么最好使用它,而不是为同一事物创建

我不知道自定义异常可以做什么,内置异常不能做什么。这似乎是一个天真的问题,但我真的不知道。
你认为呢?

在.NET中只有少数例外情况是以特殊的方式处理的,例如,它们(通常)不能被捕获、处理和吞咽


除此之外,异常类型只是异常类型。您可以对自己的异常执行与对框架中定义的异常执行几乎相同的操作。

在以下情况下,创建自定义异常非常有用:

  • 没有表示错误条件类型的内置异常
  • 您希望只捕获特定类型的异常,而不捕获来自框架的异常

但通常情况下,如果框架中已经存在可以使用的异常,那么最好使用它,而不是为同一事物创建自己的异常。

您可以使用它来实现与应用程序相关的特殊错误处理。假设您构建了一个香蕉应用程序,那么您可能会有一个
OutOfBananasException
。如果你的应用程序出了问题,你可以抛出异常,然后用特殊的错误处理来捕获它

try
{
    EatBananas();
}
catch(OutOfBananasException oobe)
{
    GetMoreBananas();
}
catch(Exception e)
{
    TellUserAndAbort();
}
编辑:
使用您自己的异常而不是内置异常的原因是为了让所有阅读您的代码或使用您的库的人都清楚发生了什么类型的错误。只有在找不到任何合适的内置异常时,才应该创建自己的异常

Edit2:

对于您自己的异常,您可以做的一件事是添加描述错误处理程序可能使用的错误条件的属性,而对于内置异常,您不能这样做。如果存在与客户相关的异常,则异常可以具有客户名称和客户id的属性,从而使错误处理程序能够向用户显示信息性错误消息。

产生不同类型异常的原因是允许您使用处理程序仅捕获所需的异常,让其他人上一层楼。因此,您可以根据异常的类型来安排捕获特定的、偶尔会出现的情况下的异常


实际上,您可能根本不需要经常创建自己的。但如果您这样做,那将是因为您需要能够抛出和捕获一种比现有异常类型更具体的异常类型,并且可能附加了附加信息。

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

  • 捕获异常中的自定义类型数据
  • 捕获自定义异常事件
  • 只有在没有需要处理的内置异常时,才应该创建自定义异常

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


    我们还有
    数据层SingleResultNoneException
    ——这是我们期望返回一个结果但没有结果的时候,以及
    数据层SingleResultManyException
    这是我们期望返回一个结果但返回多个结果的时候。这使我们能够发现不同的问题并采取相应的行动。

    这里概述了自定义异常的好处,但在创建自己的异常之前,请确保BCL没有适合您需要的异常:


    (共有141个!)

    内置异常的一个烦恼是,在表明

  • 操作失败,但重试可能成功;系统状态与尝试操作前相同。
  • 操作失败,重试可能没有帮助;尽管如此,系统状态与尝试操作前相同;
  • 操作失败,可能会损坏其他内容。 捕获异常并根据捕获异常的位置重新显示三个自定义异常之一(定义见上文)可能很有用。当异常被重试时,将原始异常作为InnerException参数传递


    顺便说一句,可以定义泛型异常。我不太确定这样做的利弊,我也从未见过其他人这样做。例如,可以定义从(自定义)TransientFaultException继承的(T的)TransientFaultException;捕获TimeoutException的应用程序可以作为(TimeoutException的)TransientFaultException重新启动,并将其捕获为(TimeoutException的)TransientFaultException或TransientFaultException。不幸的是,要创建正确的泛型,必须知道要教授的异常类型。如果捕获一个异常并将其传递给TransientFaultException的工厂方法,那么不管最初抛出的异常类型是什么,新异常都将是TransientFaultException(of Exception)类型。

    今天早上我坐下来吃麦片时抛出了这个异常!呵呵,我喜欢你用“香蕉”这个词的方式,比如说^太好了。现在我饿了。99%的情况下,我创建自己的异常类,但最终将其删除为无用。在上面的示例中,我可能会使eatbananers()返回布尔成功,而不会抛出异常。当然,如果有三种可能的回答……我也是,托尼;我想不起我实际使用过的自定义异常类。但我不知道;ArgumentNullException似乎不足以替代OutOfBananasException!顺便说一句:如果您想将更多信息附加到现有异常,您还可以对其使用(鲜为人知的).Data属性(请参阅)