无异常的错误处理

2024-01-04

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

MSDN 和许多其他著名的开发资源都非常清楚地表明异常是不用于处理常规错误情况。它们仅用于特殊情况和由于程序员(而非用户)使用不当而可能发生的意外错误。在许多情况下,诸如字段留空之类的用户错误是常见的,并且我们的程序无法处理这些错误。should预期,因此不是异常,也不是使用异常的候选者。

QUOTE:

请记住该术语的使用 编程中的异常必须做 认为有一个例外 应该代表一个特殊的 健康)状况。特殊的条件,由 他们的本质,通常不会 发生;所以你的代码不应该抛出 例外是日常生活的一部分 运营。

不要抛出异常来发出信号 经常发生的事件。考虑 使用替代方法进行沟通 对于呼叫者来说,这些情况的发生 事件和留下例外 当事情真正发生时抛出 平凡的事情发生了。

例如,正确使用:

private void DoSomething(string requiredParameter)
{
if (requiredParameter == null) throw new ArgumentExpcetion("requiredParameter cannot be null");
// Remainder of method body...
}

使用不当:

// 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. 让该方法返回一个 枚举结果? 重命名Result.成功, 重命名结果。太短, 重命名结果。太长, RenameResult.InvalidCharacters 等

  2. 在控制器类中使用事件 向UI类报告?用户界面调用 控制器的 RenameItem 方法,然后处理 控制器引发的 AfterRename 事件和 将重命名状态作为事件参数的一部分?

  3. 控制类直接引用 并调用 UI 类中的方法 处理错误,例如报告错误(字符串文本)。

  4. 还有别的事吗...?

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


根据对问题的回答,我觉得我必须用更具体的术语来陈述问题:

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

  1. 用户在 UI 中输入值。
  2. UI 向 BLL 报告值。
  3. BLL 对值执行例行验证。
  4. BLL 发现违反规则的情况。
  5. BLL 将规则违规返回给 UI。
  6. UI 接收来自 BLL 的返回并向用户报告错误。

由于用户输入无效值是例行公事,因此不应使用异常。无例外地执行此操作的正确方法是什么?


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

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

  1. 异常是可序列化的
  2. 例外总是有一个Message人类可读的属性,并且可以具有其他属性以机器可读的形式记录异常的详细信息。
  3. 一些业务规则失败实际上可能是由异常发出的信号 -FormatException, 例如。您可以捕获该异常并将其添加到列表中。

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


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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

无异常的错误处理 的相关文章

随机推荐

  • 使用 opencv 流式传输 m3u8 文件

    我正在尝试使用 python 中的 cv2 和以下代码从 GoPro 捕获实时流 VIDEO URL http 10 5 5 9 8080 live amba m3u8 cam cv2 VideoCapture VIDEO URL cv2
  • 从 csv 字符串中进行 SQL 搜索

    我正在做一个搜索页面 我必须使用单个文本框搜索多个字段 所以我将在存储过程中以 CSV 字符串形式获取搜索文本 我的表如下 ID Name age 5 bob 23 6 bod harry 34 7 charles 44 我需要一个像这样的
  • 声明“extern struct cpu *cpu asm("%gs:0");”是什么意思意思是?

    当我阅读 xv6 源代码时 我对下面声明的语法感到困惑 谁能给我解释一下吗 extern struct cpu cpu asm gs 0 我假设你明白什么extern struct cpu cpu方法 你的问题是 asm gs 0 部分意思
  • 角度,指令中,向模板添加带有 ng 模型的元素

    我正在尝试在指令中添加带有 ng model 的输入元素 my code http jsfiddle net Ajsy7 1 我的指令的链接功能 link function scope element attrs var elem 0 an
  • 读取/解密加密的XML文件,然后进行内部处理

    我过去曾使用此代码来写入和读取 xml 文件 这次我想编写一些加密的生成的 XML 然后读取它并在内部处理它 我将发布代码 也许有人可以发现问题 当我测试解密时 我已经能够输出一个具有连续行空字符代码的文件 加密文件似乎包含数据 并且随着数
  • 如何在 Windows 上将 svn 存储库转换为 git

    我们有远程 svn 存储库 我们希望将其转换为 git 你能告诉我如何在 Windows 上做到这一点吗 感谢 在 Windows 上安装应用程序 适用于 Windows 的 Git https github com git for win
  • 如何在 Windows 8.1 x64 上安装 VB6 SP6?

    需要直接在最新的操作系统中支持一些旧项目 而不是在虚拟机中 我已成功从 VS6 磁盘 1 安装了 VB6 但无法为此开发环境安装 SP6 当我启动它时 会出现一个信息窗口 通知我安装进度几毫秒 但系统文件夹中所需的文件 ADVPACK DL
  • 如何限制角度 $q 承诺并发?

    我该怎么做 q all但限制同时执行的承诺数量 我的问题就像如何限制 Q Promise 并发数 https stackoverflow com q 20546373 135114 我希望一次生成的进程不超过 5 个 另一个问题的公认答案是
  • Google Charts API:在图例单击上显示/隐藏系列。如何?

    我在网上找到了以下代码 并希望将其改编为我现有的代码 这是显示 隐藏数据系列的代码点击我发现 http jsfiddle net asgallant 6gz2Q http jsfiddle net asgallant 6gz2Q 到目前为止
  • 安卓、摇篮。如何开始具体的仪器测试方法?

    当我想启动特定的本地单元测试 在文件夹 test 中 时 我开始 Dev是构建类型 gradlew testDevUnitTest tests com example StringUtilTest testMethod 好的 是工作 但我也
  • “添加新约束”复选框和字段被禁用

    我有一个项目正在从 Xcode 4 6 3 升级到 Xcode 6 1 1 我在 Xcode 6 1 1 中打开它 并打开每个 xib 每个 xib 的格式按预期更改 我想尝试使用自动布局 选中 使用自动布局 和 使用尺寸类别 我将每个适当
  • HTML 表单回发后隐藏字段不会更新

    Html HiddenFor model gt model JobIndicator 提交页面后 JobIndicator 的值不会刷新 当我将其显示在显示字段中时 我可以看到该值正在更新 将其放入您的控制器中 ModelState Rem
  • SQLAlchemy 中的 contains_eager 和限制

    我有两节课 class A Base id Column Integer primary key True name Column String children relationship B class B Base id Column
  • 使用 Spark 运行纱线不适用于 Java 8

    我的集群有 1 个主节点和 6 个从节点 它使用预构建版本的 hadoop 2 6 0 和 Spark 1 6 2 我在所有节点上安装 openjdk 7 时运行 hadoop MR 和 Spark 作业 没有任何问题 但是 当我在所有节点
  • sfinae 使用 decltype 检查静态成员

    我编写了以下代码来尝试检测类型是否具有静态成员变量 不幸的是 它总是返回该变量不存在 有人能告诉我哪里出错了吗 我正在使用 g 4 7 1 include
  • VueJS - 使用 vue-test-utils 进行单元测试给出错误 - TypeError: _vm.$t 不是函数

    对于 Vuejs 来说相对较新并正在测试其组件 使用 vue test utils 和 jest 进行测试 出现以下错误test log https i stack imgur com rQejp jpg vue 文件由模板 组件和样式组成
  • 为什么在 golang 中仅初始化定义中的一个变量会失败

    在调用具有以下签名的库函数时 func New sql DB Sqlmock error 像这样 suite db suite mock err sqlmock New inside a suite method 我收到错误 expecte
  • 二值化图像中的单独交叉线段

    我有一些图像处理 允许我提取包含厚片段的二进制图像 并且我面临着这些片段可能相互交叉的问题 因此 我需要找到一种有效的方法来分离它们 我必须在 C 中实现它 这样任何基于 OpenCV 的东西都会有所帮助 这是一个示例输入图像 两个 斑点
  • gcc 是否有任何选项可以在 ELF 二进制文件中添加版本信息?

    我的意思是 gcc 是否可以将一些源代码版本信息作为部分或类似的内容插入到 ELF 二进制文件中 我不想更改我的源文件 但在 Makefile 中使用 gcc 选项添加一些信息 如果您不介意只更改源文件一次 请添加如下内容 const vo
  • 无异常的错误处理

    在搜索与业务规则验证相关的错误处理方法时 我遇到的只是结构化异常处理的示例 MSDN 和许多其他著名的开发资源都非常清楚地表明异常是不用于处理常规错误情况 它们仅用于特殊情况和由于程序员 而非用户 使用不当而可能发生的意外错误 在许多情况下