C# 澄清:尝试Catch vs抛出异常以及为什么调用基类构造函数

C# 澄清:尝试Catch vs抛出异常以及为什么调用基类构造函数,c#,.net,exception,custom-exceptions,C#,.net,Exception,Custom Exceptions,按照书中的示例,获得了以下稍加修改的代码: class OutOfHoneyException : Exception { public OutOfHoneyException(string message) :base(message){} } class HoneyDeliverSystem { public void FeedHoneyToEggs() { if (true) {

按照书中的示例,获得了以下稍加修改的代码:

 class OutOfHoneyException : Exception
 {
    public OutOfHoneyException(string message) :base(message){}
 }

    class HoneyDeliverSystem
    {
        public void FeedHoneyToEggs()
        {
            if (true)
            {
                throw new OutOfHoneyException("This hive is Out Of Honey");
            }
        }
    }
"

 HoneyDeliverSystem delivery = new HoneyDeliverSystem();

      try
        {
            delivery.FeedHoneyToEggs();
        }
        catch (OutOfHoneyException ex)
        {

            Console.WriteLine(ex.Message);
        }
我所理解的是,当我们在特定条件下抛出特定异常时,相应的catch块会处理该异常

但请帮我举一个更好的例子,也许.NETException的实现会非常有用

为什么我们要将消息传递给基
异常
类?它只用于印刷吗


对于调用基类构造函数的子类,有一个OOPS概念。您能说出它的名称以及它与自定义异常的关系吗?例如。

您离常规做法不远。我会这样做:

class OutOfHoneyException : Exception {
  public OutOfHoneyException() : base("This hive is Out Of Honey"){}
}

class HoneyDeliverSystem {
  public void FeedHoneyToEggs() {
    throw new OutOfHoneyException();
  }
}

我的意思是,没有理由为一个
OutOfHoneyException
使用不同的消息,是吗?

当您将消息传递给基类(异常)时,基类将设置异常的message属性,并执行所有有用的操作,如保留StackTrace

因此,当捕获自定义异常(OutOfHoneyException)时,消息字段将由基本异常类设置。从实现中签出以下代码:

/// <summary>
/// Initializes a new instance of the <see cref="T:System.Exception"/> class with a specified error message.
/// </summary>
/// <param name="message">The message that describes the error. </param>
public Exception(string message)
{
  base..ctor();
  this.Init();
  this._message = message;
}

/// <summary>
/// Initializes a new instance of the <see cref="T:System.Exception"/> class with a specified error message and a reference to the inner exception that is the cause of this exception.
/// </summary>
/// <param name="message">The error message that explains the reason for the exception. </param><param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. </param>
public Exception(string message, Exception innerException)
{
  base..ctor();
  this.Init();
  this._message = message;
  this._innerException = innerException;
}
//
///使用指定的错误消息初始化类的新实例。
/// 
///描述错误的消息。
公共异常(字符串消息)
{
base..ctor();
this.Init();
这个。_message=消息;
}
/// 
///使用指定的错误消息和对导致此异常的内部异常的引用初始化类的新实例。
/// 
///解释异常原因的错误消息。导致当前异常的异常,或者如果未指定内部异常,则为空引用(在Visual Basic中为Nothing)。
公共异常(字符串消息,异常innerException)
{
base..ctor();
this.Init();
这个。_message=消息;
这。_innerException=innerException;
}

我将尝试回答您的具体问题,而不是写一个答案告诉您如何创建异常

为什么我们要将消息传递给基异常类?它只用于印刷吗

或多或少。该消息将向异常添加上下文。可能有几个原因可以解释为什么会抛出“出于个人”的例外——蜜蜂睡着了,它们在度假,食蚁兽用完了蚂蚁,决定改为喜欢蜜蜂,等等

对于调用基类构造函数的子类,有一个OOPS概念。你能说出它的名字以及它与自定义异常的关系吗


无论在派生类上使用哪个构造函数,除非指定不同的构造函数(这里就是这样),否则默认构造函数将始终在基类上调用。这是基本的,它在创建派生类时为您提供了合理的灵活性(还请注意,有)

最好的办法是将新异常放入它自己的文件中,并将其公开。基本
Exception
类有4个构造函数,在大多数情况下,至少实现前3个构造函数会很有用:

public class OutOfHoneyException : Exception
{
    public OutOfHoneyException()
        : base()
    {
    }

    public OutOfHoneyException(string message)
        : base(message)
    {
    }

    public OutOfHoneyException(string message, Exception innerException)
        : base(message, innerException)
    {
    }

    public OutOfHoneyException(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
    }
}
您从
Exception
类继承,因为它具有处理自定义异常时所需的所有基本异常实现/行为

您需要实现所有4个构造函数,以使新的自定义异常感觉更像一个典型的.NET异常

在学习异常时,有两件事需要注意:第一,异常应该只针对异常行为抛出;第二,异常不应该用于控制程序流。这两条规则有点相配


例如,如果您查询库存控制系统以查看库存中有多少罐豆类,那么结果为0将是一个常见的答案,尽管这不是客户想要的答案,但也不例外。如果您在库存系统中查询豆子罐头,而数据库服务器不可用,这是超出您预期的常见结果之外的异常行为。

您的代码甚至无法编译。您想要的是
:base
而不是
base
。原因是要正确初始化基类——它将为您设置
消息
属性。相关:如果创建异常,请实现公共异常构造函数(带有
消息
内部异常
的构造函数)。感谢您的更正,可以为自定义消息创建一个reasn-它为异常添加上下文。