何时创建新的异常类型而不是使用.Net中的一个内置异常有什么指导原则?
让我思考的问题是这个。我有一个WCF服务,这是一个基本的输入输出服务。如果服务无法创建输出,因为输入无效,我想抛出异常,但是哪一个?
现在我只是抛出system.Exception,但这对我来说感觉不对,我不知道为什么,这只是感觉不对。 有一件事让我感到困惑,如果我用单元测试测试它,我希望抛出system.Exception。该异常也可以由框架或其他代码抛出,而不是由我抛出的代码抛出。然后测试将通过,因为我得到预期的异常,但它应该失败。
你推荐什么?
答案 0 :(得分:15)
避免自己投掷System.Exception
或System.ApplicationException
,因为它们过于笼统。
对于WCF服务,存在故障合同 - 您可以告诉子公司要处理的一般例外。
将界面标记为:
[FaultContract( typeof( LogInFault ) )]
void LogIn( string userName, string password, bool auditLogin );
然后,如果有异常,您可以抛出此特定错误:
throw new FaultException<LogInFault>( new LogInFault(), "message" );
对您的错误使用[DataContract]
序列化 - 这使您无需处理通常需要的所有序列化内容。
答案 1 :(得分:7)
绝对避免为抛弃代码以外的任何东西抛出System.Exception。
如果方法的参数无效,则抛出ArgumentException(或某些派生的,更具体的异常)。在创建自己的异常之前,请查阅文档以获取现有异常 - 但这样做通常很有用。 (当然,您可以从ArgumentException派生自己的异常类型 - 如果您想要从多个位置指示某种特定类型的条件,则创建新类型会提供更多信息,而不仅仅是将其放入错误消息中。 )
现在WCF中的错误处理可能与“普通”框架中的错误处理不同 - 我建议你参考WCF特定的文档/书籍。
答案 2 :(得分:2)
抛出System.Exception并不是一个好主意。最大的原因是它对调用代码的影响。他们应该如何处理这个例外?如果调用代码要处理异常,那么他们必须捕获每个异常,这可能不是他们做的最好的事情。
如果其中一个标准异常没有涵盖某种情况,那么你应该创建一个新的Exception对象,如果异常是调用代码作为特殊情况应该处理的东西。
答案 3 :(得分:2)
System.Exception只能用作异常的基类,不能直接抛出。
框架已经提供了许多有效的异常类,如ArgumentException,ArgumentNullException,InvalidOperationException,FormatException,OverflowException等......
你说你正在做I / O的事情,所以一个好主意是在框架中查看类似的操作(比如int.Parse)并为类似的错误抛出相同的异常。
或者从现有的异常类派生自己的异常类,如果它们都不能满足您的需求。
答案 4 :(得分:2)
如果抛出System.Exception,则调用者必须捕获System.Exception。这两方面都是禁忌,因为它让我们告诉用户“这不起作用”,而不是更有用的东西。
如果调用者传入了无效参数,则ArgumentException非常有用。如果你的函数有一个你需要是偶数的int参数,那么你会抛出并且ArgumentException告诉调用者什么参数是无效的以及为什么。但是,如果所有参数都有效但仍存在问题,则可能需要自定义异常。通过这种方式,呼叫者可以激动地告诉用户出了什么问题。
对我的测试真的是在呼唤方面。如果我有十几个捕获所有都做同样的事情,那么我真的只需要一个例外。但是,如果我有一个捕获并且有一个声明告诉用户三个出错的地方之一,那么我真的需要三个独特的例外。
答案 5 :(得分:1)
什么时候有什么指导方针 创建一个新的异常类型而不是 使用其中一个内置异常 在.Net?
当没有合适的预定义异常类时 .NET FW非常丰富,通常可以找到预定义的异常。
如果服务无法创建 输出,因为输入无效
ArgumentException Class (System)
一个引发的异常 提供给方法的参数 无效。
答案 6 :(得分:0)
始终创建新的异常类型(如果适合您,请使用标准类型)。
在这种情况下,您可以作为一个组处理异常。
答案 7 :(得分:0)
正如之前的海报所述,你不应该抛出System.Exception。实际上,如果您在代码上运行FxCop,它会将其标记为规则违规。
我建议您查看Applied .NET Framework Programming的第18章,或者通过C#(第2版)查看最近的CLR的第19章,以获取详细的指导。里希特在纠正很多开发人员对异常的误解方面做得非常出色。
这两本书都包含框架类库定义的例外列表。查看列表并找出代码可能抛出的最具体的异常。如果您可以从异常中恢复,请在该catch块中执行此操作。如果您需要多个catch块,请将它们从最具体到最不具体的组织起来。如果在现有列表中找不到适合该情况的自定义异常,请创建自定义异常。