首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >无异常的错误处理

无异常的错误处理
EN

Stack Overflow用户
提问于 2009-08-13 14:32:59
回答 6查看 5.9K关注 0票数 25

在搜索与业务规则验证相关的错误处理方法时,我遇到的都是结构化异常处理的示例。

MSDN和许多其他有声誉的开发资源都非常清楚,异常不能用于处理例程错误情况。它们仅适用于因程序员(而不是用户)使用不当而可能出现的异常情况和意外错误。在许多情况下,用户错误(如字段留空)很常见,这是我们的程序应该预料到的事情,因此不是异常,也不适合使用异常。

引用:

请记住,在编程中使用术语exception与认为异常应该代表异常条件的想法有关。从本质上讲,异常情况通常是不会发生的;因此,您的代码不应该在其日常操作中抛出异常。

不会抛出异常来通知通常发生的事件。考虑使用替代方法来通知调用者这些事件的发生,而将异常抛出留给真正不寻常的事情发生。

例如,正确使用:

代码语言:javascript
复制
private void DoSomething(string requiredParameter)
{
if (requiredParameter == null) throw new ArgumentExpcetion("requiredParameter cannot be null");
// Remainder of method body...
}

使用不当:

代码语言:javascript
复制
// Renames item to a name supplied by the user.  Name must begin with an "F".
public void RenameItem(string newName)
{
   // Items must have names that begin with "F"
   if (!newName.StartsWith("F")) throw new RenameException("New name must begin with /"F/"");
   // Remainder of method body...
}

在上述情况下,根据最佳实践,最好是将错误向上传递到UI,而不涉及/需要.NET的异常处理机制。

使用上面的相同示例,假设需要对项目强制执行一组命名规则。什么方法是最好的?

让方法返回枚举结果的

  1. ?RenameResult.Success、RenameResult.TooShort、RenameResult.TooLong、RenameResult.InvalidCharacters等。
  2. 是否使用控制器类中的事件向UI类报告?UI调用控制器的RenameItem方法,然后处理控制器引发的AfterRename事件,该事件将重命名状态作为事件参数的一部分?
  3. 控制类直接引用和调用处理错误的UI类中的方法,例如ReportError(string
  4. ...?

从本质上讲,我想知道如何在可能不是Form类本身的类中执行复杂的验证,并将错误传递回Form类进行显示--但我不想在不应该使用它的地方涉及异常处理(尽管它看起来容易得多!)

根据对这个问题的回答,我觉得我必须用更具体的术语来说明这个问题:

UI =用户界面,BLL =业务逻辑层(在本例中,只是一个不同的类)

  1. 用户在UI中输入值。
  2. UI将值报告给BLL。
  3. BLL对该值执行例程验证。
  4. BLL发现规则BLL将规则冲突返回给UI。
  5. UI从BLL接收返回并向用户报告错误。

由于用户输入无效值是例行公事,因此不应使用异常。没有例外的正确方式是什么?

EN

回答 6

Stack Overflow用户

发布于 2009-08-13 15:04:40

我假设您正在创建自己的业务规则验证引擎,因为您还没有提到您正在使用的引擎。

我会使用异常,但我不会抛出它们。您显然需要在某个地方累积评估的状态--为了记录特定规则失败的事实,我将存储一个描述该失败的异常实例。这是因为:

  1. Exceptions是指始终具有人类可读的Message属性的业务规则异常,并且可以具有以计算机可读形式记录异常详细信息的附加属性。
  2. 某些业务规则故障实际上可能已由异常发出信号,例如FormatException。您可以捕获该异常并将其添加到列表中。

事实上,本月的MSDN Magazine有一篇文章提到了.NET 4.0中的新AggregateException类,这意味着它是在特定上下文中发生的异常的集合。

由于您使用的是Windows Forms,因此应该使用内置的验证机制:Validating事件和ErrorProvider组件。

票数 5
EN

Stack Overflow用户

发布于 2009-08-13 14:41:10

我认为你对预期信息的理解是错误的。这是我昨天从current edition of Visual Studio magazine上看到的一句很棒的话(第19卷,第8期)。

成员要么履行合同,要么抛出excetion。句号。没有中间立场。没有返回码,不,有时有效,有时不起作用。

应该小心使用异常,因为它们的创建和抛出成本很高--但是,它们是.NET框架通知客户端(我指的是任何调用组件)错误的方式。

票数 4
EN

Stack Overflow用户

发布于 2009-08-14 17:34:43

我同意Henk的部分建议。

传统上,“通过/失败”操作被实现为具有整数或布尔返回类型的函数,该类型将指定调用的结果。然而,一些人反对这一点,声明“函数或方法应该执行操作或返回值,但不能同时执行这两种操作。”换句话说,返回值的类成员不应该也是更改对象状态的类成员。

我已经找到了在生成错误的类中添加.HasErrors/.IsValid.Errors属性的最佳解决方案。前两个属性允许客户端类测试是否存在错误,如果需要,还可以读取.Errors属性并报告包含的一个或所有错误。然后,每个方法都必须知道这些属性,并适当地管理错误状态。然后,可以将这些属性合并到各种业务规则层外观类可以合并的IErrorReporting接口中。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1272342

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档