C# 何时抛出异常
虽然我读了很多关于异常处理的书,但我仍然不确定什么时候抛出异常,什么时候不抛出异常 例如,我有一个API作为三层架构,在DB层中可能会发生事件C# 何时抛出异常,c#,oop,exception,C#,Oop,Exception,虽然我读了很多关于异常处理的书,但我仍然不确定什么时候抛出异常,什么时候不抛出异常 例如,我有一个API作为三层架构,在DB层中可能会发生事件 尝试从数据库接收客户,但找不到具有给定id的客户 尝试按id删除客户,但在数据库中找不到该id 尝试按id更新客户,但在数据库中找不到该id 在第一种情况下,我没有抛出异常,因为没有什么真正的“出错”。我的存储库函数只返回“null”,告诉上层什么也没找到。 但另外两个案例已经很棘手了 如果找不到id,deleteById函数返回“null”,这对我
- 尝试从数据库接收客户,但找不到具有给定id的客户
- 尝试按id删除客户,但在数据库中找不到该id
- 尝试按id更新客户,但在数据库中找不到该id
true
/false
返回来表示,则可以在更复杂的场景中声明enum
作为返回值,甚至是元组
尝试从数据库接收客户,但找不到具有给定id的客户
尝试按id删除客户,但在数据库中找不到该id
尝试按id更新客户,但在数据库中找不到该id
DB应该很好地处理所有这3种可能的情况,当出现这种路径时,只需向调用者返回一个值,并提供足够的信息,以便调用者能够处理结果并正确操作。我认为,在任何情况下都不应该抛出异常-原因如下:
异常应该用于异常情况-主要是代码中无法控制的情况-例如网络连接错误等。
对非异常情况抛出异常只是,嗯,令人烦恼,正如Eric Lipprt所说
-
尝试从数据库接收客户,但找不到具有给定id的客户
好吧,这是一个不需要动脑筋的问题-您在数据库中没有找到客户-返回null。没有理由抛出异常,因为在这种情况下没有异常
-
尝试按id删除客户,但在数据库中找不到该id
如果在数据库中找到该客户,则此操作将导致删除该客户。
如果在数据库中找不到它——最终结果仍然与找到它时一样——那么你为什么要首先关心它不在那里呢?同样,没有理由抛出异常
-
尝试按id更新客户,但在数据库中找不到该id
这是最难解释的,但基本上有两种合法的方法来处理这种情况:
一种方法是,当update语句的where子句不适合表中的任何行时,执行任何数据库所执行的操作,即什么也不做。
至于让客户机知道是否有实际的更新或没有操作,您可以检查生效的行数,并将true/false或customer/null返回给客户机
另一种方法是将更新转换为“upserts”——因此,如果在数据库中找不到客户,只需创建一个新客户即可。
也可以使用简单的真/假返回值将其指示回客户机。在这种情况下,您应该正确地命名方法-AddOrUpdateCustomer
。当出现意外错误时,您必须抛出异常。用你的例子=>
getById调用返回项|如果未找到则为null=>如果不存在则没有错误
repo.Delete函数必须有一个有效的id=>db函数抛出异常(如果ArgumentException更好)。。。但控制器/管理器需要捕获(ArgumentException),然后捕获两个选项:
2a.“删除不存在项“=>success->after方法调用,项
不存在
2b。es:控制器向客户端发送错误消息“您要删除的项目不存在”
repo.Update函数必须具有有效的id=>如上所述,不带2a选项
如果函数需要此参数=>throw
如果函数manage'not found=null'case=>not throw那么,这里真正的问题是,为什么要删除或更新数据库中不存在的客户?通常,所有my deletes都返回一个int,表示删除的项目数。更新也是如此。您可能有更新多个项目的更新。按ID更新只是一个特殊的更新。仍然可以返回相同的东西。我倾向于不偏不倚,并且对它想得太多。不过,这取决于个人喜好。因此,您可以通过业务逻辑将更新、删除的项目数量的信息传递给最高层,而不会抛出异常。。。是的,这就是我现在要做的,但是使用“true”、“false”…当delete或update获得无效Id时,我会抛出一个异常。我认为这是避免可能发生的任何问题的最简单方法。当您调用这两个逻辑时,您必须捕获错误并向用户发送一条消息,说明他/她做了什么或没有做什么。永远不要让错误到达用户,因为它存在安全漏洞。ArgumentException用于无效参数。如果是删除操作,则为最终结果