抛出异常或返回错误 - 更好的方法是什么?

时间:2012-01-28 17:55:20

标签: c# winforms exception exception-handling

处理错误时有什么更好的方法 - 将其作为异常抛出或返回包含错误及其详细信息的对象?

我在想什么是更好的通知错误的方法 - 在系统资源,编码实践和整体企业实践方面?

在大多数情况下,我看到示例代码会抛出包含错误信息的自定义异常。但我在想是否最好只返回一个从类中实例化的对象(例如:类DatabaseError)?

我认为在C#中抛出异常可能是资源密集型的,这可能涉及(可能)大量的try-catch块。

谢谢!

3 个答案:

答案 0 :(得分:2)

  

请勿返回错误代码。

     

例外是在框架中报告错误的主要方法。

- Framework Design Guidelines

有关详细信息和处理绩效的方法,请参阅这本优秀的书。

答案 1 :(得分:2)

异常通常被认为是将应用程序链中的错误条件中继到可以处理和管理它们的方式的首选机制,它们不会导致应用程序完全失败并终止。

但是,将异常处理机制用作逻辑路径通常也被认为是不好的做法 - 也就是说,将捕获错误条件作为以后正确或替代功能的先决条件(例如,尝试打开可能存在或不存在的文件,如果它不存在则捕获该异常,并在结果中显示文件浏览器对话框 - 在此示例中,在尝试打开文件之前应检测到“NOT FOUND”错误条件,而不是将异常路径视为要求用户定位它的路径。)

答案 2 :(得分:2)

当调用者期望可能发生某种情况时,最好通过返回码通知调用者该条件。当出现调用者不期望的情况时,最好通过异常通知调用者。

因为大多数语言都没有为被调用例程提供任何方法来“神奇地”知道调用者期望什么,所以例程知道调用者期望的唯一方法是让调用者告诉它。我建议有一些模式:

  1. 同时使用“DoSomething”方法和“TryDoSomething”方法。如果前者无法实现预期目标,前者将抛出异常,而后者则抛出异常。
  2. 使用带有布尔值或枚举参数的单个方法,该参数指示例程是否应该表现为“尝试”或“执行”方法。这通常与小的“DoSomething”和“TryDoSomething”方法结合使用,这些方法调用组合例程传递适当的参数值。虽然许多实现会使组合例程受到保护,但将其公开可以允许从另一个“Do或Try”例程调用它,将ThrowOnFailure值从另一个例程传递给内部例程。
  3. 使用包含或不包含“ref”参数的重载的单个方法,该参数将用于指示成功或失败。带参数的函数版本将使用它来指示失败(不抛出异常),而没有它的重载将在失败的情况下抛出异常。
  4. 拥有一个带有委托的方法,如果发生故障,应该调用该方法。从概念上讲,这是一种比传递布尔参数更好的方法,因为委托不仅可以抛出一个异常,调用代码将准备捕获;它还可以设置标志或采取其他操作,因此当调用代码捕获异常时,可以确定实际发生了什么。不幸的是,找出代表的最佳形式,包括它应该采取什么参数,是棘手的。

方法#1似乎是微软推荐的模式,但我认为#2可以帮助避免重复编码。方法#3将类似于几年前在Borland Pascal中使用的惯例,这种方法相对直观地得出。方法#4似乎是最好的,但我还没弄清楚如何最好地做到这一点。