自定义异常类

时间:2011-09-16 18:14:10

标签: c# .net exception-handling

我有一个抽象类Camera。有一些派生类可以处理特定类型的摄像机。每种类型的相机都有自己的异常,而其中一些根本没有异常,它们会返回一个错误类型的枚举。

我想知道你们是否同意这种实施方式:

所有特定的类都将处理它们的异常(或枚举错误类型)并将其转换为一般异常(例如:CameraException:Exception)并抛出它。

这是一个好的/推荐的实施吗?

4 个答案:

答案 0 :(得分:3)

您可能希望将错误概念统一到一个通用的CameraException类层次结构中。如果目标是抽象相机实现,您应该将错误抽象到这个常见的异常框架中。

如果您只有特定于实现的例外,那么您的班级用户将很难在不分析详细信息的情况下准确理解CameraException试图说出的内容。

我建议提供逻辑异常框架,然后依赖于实现的相机逻辑将解释代码,然后创建正确的相应逻辑相机异常。

例如,如果您尝试在相机的内存,卡上执行操作,并且未插入任何操作,请抛出NoMemoryCardInCameraException,该CameraException可以从CameraException继承。

如果确实希望这些提供商详细信息可用,那么您可以在Detail中使用名为Dictionary的属性或者是抽象类或{{具有实现特定细节的键值对的1}}。这样,如果有人真的想从提供商那里深入挖掘实际的错误代码,枚举等等。

您的目标应该是普通用户能够捕获逻辑异常并正确处理它们而不需要 来了解具体情况。

希望澄清一下......

答案 1 :(得分:2)

如果调用者要捕获该特定类型,或者某个调用者将了解特定类型并查看其属性,则应该只创建一个新的Exception类型。

如果不同摄像机类型的呼叫者只做以下操作:

try
{
    // Do something with some kind of camera
}
catch (CameraException ex)
{
    // Handle the fact that there was a camera problem
}

然后不需要CameraException的自定义派生类型。没有人关心抛出特定衍生类型的东西。

事实上,如果你的调用者在抛出CameraException时与其他任何异常没什么不同,那么就不需要CameraException。只需使用类似InvalidOperationException的内容,并将其与信息性Message属性一起投放:

throw new InvalidOperationException(
    String.Format("Invalid attempt to set the f-stop to {0} while in video mode",
                  this.FStop));

答案 2 :(得分:2)

应用层应该定义自定义异常类型,无论微软说什么。假设有一个抽象的WrappedCamera类,其衍生产品可以作为CanonCamera,NikonCamera,KodakCamera等类的包装器,其未来的衍生产品将作为未来设计的相机类的包装。假设WrappedWaldorfCamera类包装WaldorfCamera,并且当它调用WaldorfCamera.GetPictureCount()时该方法抛出异常WaldorfCamera.WrongCameraModeException。如果WrappedWaldorfCamera允许异常渗透,那么应用程序将使用它做什么?除非应用程序假定所有未知异常类型都应显示消息但允许程序继续,否则应用程序无法知道WaldorfCamera.WrongCameraModeException是否可以安全捕获。相比之下,如果WrappedWaldorfCamera抛出从WrappedCamera.CleanNonConnectStateException派生的WrappedCamera.CameraModeException,应用程序将知道它应该捕获异常并处理它。

BTW,以免任何人抱怨整个“问题”是由WaldorfCamera定义自己的异常创建的,考虑到WrappedWaldorfCamera允许渗透InvalidOperationException的情况。应用程序应该如何处理其中一个?

正确的做法是让每个应用程序层至少定义致命和非致命异常类型 - 通常根据应用程序状态具有几种风格(例如,CleanNonConnectStateException意味着特定的摄像机 - 连接对象没有有效的连接;准备处理的应用程序代码应该捕获异常,而未准备处理的代码应该让异常冒泡到代码可以处理这种情况,重新封装如果它穿过另一个图层边界则是例外。

答案 3 :(得分:0)

转换为通用异常通常只是隐藏重要信息 让所有异常继承CameraException都是件好事,但如果发现它有用,请让不同的实现子类CameraException