【发布时间】:2009-06-23 13:09:28
【问题描述】:
我正在我的应用程序中创建一些自定义异常。
如果我在测试参数状态后抛出异常,或者在测试 int 在适当范围内后抛出异常,我的异常应该继承 ArgumentException 和 IndexOutOfRangeException 还是应该继承例外?
【问题讨论】:
我正在我的应用程序中创建一些自定义异常。
如果我在测试参数状态后抛出异常,或者在测试 int 在适当范围内后抛出异常,我的异常应该继承 ArgumentException 和 IndexOutOfRangeException 还是应该继承例外?
【问题讨论】:
由于继承用于指定要捕获的异常,因此在做出决定时应首先尊重这一点。
想想携带附加信息的 IOException,或 ArgumentOutOfRangeException 或 ArgumentNullException 以外的 ArgumentException。
【讨论】:
假设您确实需要自定义异常,我会从最符合您要求的异常继承,而不仅仅是从异常继承。
也就是说,我发现在大多数情况下,在异常消息中使用正确的措辞通常足以创建一个全新的异常。
例如,throw new IntOutOfProperRangeException(); 与 throw new ArgumentOutOfRangeException("The int value was too large?"); 有何显着不同
【讨论】:
我认为创建一个新的异常类型总是更安全。如果您需要更改处理方式,则更容易找到您正在或可能正在处理它的案例。查找 MyException 比查找 ArgumentOutOfRangeException 的具体情况要容易得多。您似乎可以在异常中提供一些额外的信息,并且创建异常并没有太多工作。
此外,我倾向于继承 MyBaseException 之类的基本应用程序类,并确保为异常添加 XML cmets。
【讨论】:
我只是好奇,你为什么不实际使用已经存在的异常?听起来这些异常正是您所需要的,您为什么反对使用它们?
【讨论】:
就我个人而言,如果我有一个索引器并且索引值超出范围,那么我会简单地抛出现有的 IndexOutOfRangeException,我不会费心去继承它。
如果您只讨论相似但不完全相同的异常,请查看框架中提供的模式。看起来这没有意义,继承描述了一种“is-a”关系。
【讨论】:
如果您不需要向异常添加任何其他数据,那么我只需使用本机 .NET 异常,例如 IndexOutOfRangeException。
但是,如果您需要将某些东西与您的异常相关联,而您不能使用 IndexOutOfRangeException 进行本机操作,那么我会继承它。这里的好处是您可以捕获新的自定义异常类型或 IndexOutOfRangeException。当然,如果你捕获了基类型,你就不会拥有额外的属性等。
【讨论】:
恕我直言,从另一个异常继承没有问题。它使该异常的目的更加清晰。但请确保适用于 ParentException 的所有内容也适用于您创建的 ChildException。否则,您最终可能会得到"Square extends Rectangle" problem...
【讨论】:
我几乎总是将 IllegalArgumentException(空值和/或超出范围的值)和 IllegalStateException 用于不比 IOException、SQLException、Null 更具体的任何事情......
【讨论】:
我认为这完全取决于您是否要将 ArgumentNotInPersitableState 异常捕获为 ArgumentOutOfRange。如果会有这样的 catch 块(或者如果您正在编写一个框架,可能会被其他人使用)那么是的,您应该继承相关的异常类型。
【讨论】:
如果您只使用通用异常,您将永远无法捕获为您的应用程序自定义的特定异常。如果你只是使用
try
{
}
catch (Exception ex)
{
}
您将捕获每个异常,但无法过滤特定错误。
我创建自定义异常的另一个原因是处理可能由于多种原因而发生的特定于应用程序的异常。这允许意味着抛出自定义异常但自定义与异常关联的消息。它还为我的特定应用程序提供了另一个级别的错误处理。
例如,我有一个工程应用程序,用于确定皮带传动系统的大小。该 dll 也可供其他人使用。 I have an application exception that is thrown when an error occurs in the selection.错误的原因可能有很多(无效的驱动速度、不正确的马力要求等)。由于失败的原因有很多,自定义应用程序异常允许我提供失败的具体细节。
这还允许我向用户记录方法调用将引发他们需要处理的应用程序特定异常。
如果您继承的 Exception 类,请确保在基类中实现具有消息、消息 + 内部异常和序列化异常的构造函数。
这是我的一个例子。
/// <summary>
/// Drive error exception class. Thrown when a drive selection error has occured.
/// </summary>
[Serializable]
public class DriveException : SystemException
{
/// <summary>
/// Default constructor.
/// </summary>
public DriveException()
{
}
/// <summary>
/// Constructor used with a message.
/// </summary>
/// <param name="message">String message of exception.</param>
public DriveException(string message)
: base(message)
{
}
/// <summary>
/// Constructor used with a message and an inner exception.
/// </summary>
/// <param name="message">String message of exception.</param>
/// <param name="inner">Reference to inner exception.</param>
public DriveException(string message, Exception inner)
: base(message, inner)
{
}
/// <summary>
/// Constructor used in serializing the data.
/// </summary>
/// <param name="info">Data stored to serialize/de-serialize</param>
/// <param name="context">Defines the source/destinantion of the straeam.</param>
public DriveException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
【讨论】:
ApplicationException (source)继承。