应该如何接口实现处理各类来电者所期望的意外内部异常?接口、异常、意外

由网友(沉溺在你眼里)分享简介:如果一个类实现一个接口,应该如何处理的情况下,无论是 在方法或属性,发生内部错误哪个是哪个呼叫者可合理地期待一个类型的执行处理,但来电者也许不应该。例如,IDictionary.Add做了一些内部而产生的情况下,一个ArgumentException这将意味着词典已损坏,但不会暗示任何关于该系统的其他部分坏?或者,他们...

如果一个类实现一个接口,应该如何处理的情况下,无论是 在方法或属性,发生内部错误哪个是哪个呼叫者可合理地期待一个类型的执行处理,但来电者也许不应该。例如,IDictionary.Add做了一些内部而产生的情况下,一个ArgumentException这将意味着词典已损坏,但不会暗示任何关于该系统的其他部分坏?或者,他们暗示一些东西被破坏超出了词典吗?呼叫者可期待捕获和处理的重复键存在于词典,因为在某些情况下,异常可能是棘手的(如在同一code可用于那些不是由其他线程和访问的字典的事实对于一个ConcurrentDictionary是,和语义将是可行的,如果试图增加一个重复记录引起清洁失败)。让一个ArgumentException渗滤液会导致调用者认为,词典是在相同的状态,如果添加从未发生过,这可能是危险的,但抛出一些其他类型的异常,似乎令人困惑。 在方法或属性的执行,发生异常调用者也许应该或不应该处理,以及接口的定义不提供任何暗示,任何偶数远程相关的异常可能发生。例如,假设不顺心的事在IEnumerator的评价,无论是暗示(1)枚举器被损坏(可能由另一个线程意外的动作),但重试枚举可能成功; (2)可枚举对象本身可能已损坏或无法使用,但系统中的其他一切也没什么问题(例如,一个懒洋洋地评估文件分析例程打一个无效的记录); (3)之外的东西枚举对象已被损坏。 IEnumerable的只有一个定义的异常可以抛出,但主叫方可能希望根据异常的严重性改变其行为。 如果我有我的druthers,该系统将定义一些类型,​​如RetryableFailureException,CleanFailureException,ObjectCorruptFailureException,大部分的接口将允许抛出那些或其衍生物。因为这不是这种情况,应如何妥善处理接口,无论是从界面或调用者的看法?

顺便说一句,我从来没见过实现,但似乎是有用的,将是方法接受一个委托参数一个模式进行的情况下该方法失败的方式,将导致一种尝试的方式返回false执行。这样的委托,由主叫方提供的,可以那么不仅抛出一个异常,收件人会知道去找,而且还可以设置一个标志,在其他方面只提供给调用者。因此,主叫方可以知道,除了被抓确实是一个预期。

解决方案

这是接口的工作是定义成员(以及他们的签名),类必须有,他们不应该怎么实现的。因此,我要说让异常泡沫堆栈。如果你真的要定义的合同,并控制一些执行(如错误处理),那么你应该做一个基类(我会倾向于一个为MustInherit /抽象类在这种情况下)与MustOverride的方法的基类的调用它的方法(在一个尝试捕捉你的情况,所以你可以做你的特殊的错误处理)。

把高校的数据服务,像水 电 气一样输送给有需要的业务部门 应用系统 开发者以及师生用户

If a class implements an interface, how should it handle the situations where either

In the execution of a method or property, an internal error occurs which is of a type which a caller might reasonably be expecting to handle, but which a caller perhaps should not. For example, IDictionary.Add does something internally which yields an ArgumentException under circumstances which would imply that the dictionary is corrupt, but would not imply anything bad about the rest of the system? Or they imply that something is corrupted beyond the dictionary? A caller may be expecting to catch and handle the fact that a duplicate key exists in the dictionary, since in some cases the exception may be Vexing (e.g. the same code may be used for a Dictionary that's not accessed by other threads and for a ConcurrentDictionary which is, and the semantics would be workable if an attempt to add a duplicate record caused a clean failure). Letting an ArgumentException percolate would lead a caller to believe that the dictionary is in the same state as if the add never occurred, which could be dangerous, but throwing some other exception type would seem confusing. In the execution of a method or property, an exception occurs which the caller maybe should or shouldn't handle, and the definition of the interface doesn't provide any hint that any even-remotely-related exception might occur. For example, suppose something goes wrong in the evaluation of IEnumerator, either implying (1) the enumerator got corrupted (possibly by unexpected action on another thread) but retrying the enumeration might succeed; (2) the enumerable object itself is probably corrupted or unusable, but everything else in the system is probably okay (e.g. a lazily-evaluated file parsing routine hit an invalid record); (3) something beyond the enumerable object has been corrupted. IEnumerable only has one defined exception it can throw, but a caller may want to vary its action based upon the 'severity' of the exception.

If I had my druthers, the system would define some types like RetryableFailureException, CleanFailureException, ObjectCorruptFailureException, and most interfaces would be allowed to throw those or derivatives thereof. Since that's not the case, how should one properly handle interfaces, either from the view of the interface or the caller?

BTW, one pattern I've not seen implemented, but would seem useful, would be for methods to accept a delegate parameter to be executed in case the method fails in a way that would cause a "try" method to return false. Such a delegate, supplied by the caller, could then not only throw an exception which the recipient would know to look for, but could also set a flag that was otherwise available only to the caller. The caller could thus know that the exception being caught was indeed the one expected.

解决方案

An Interface's job is to define the members (and their signatures) that a class must have, not how they should be implemented. Therefore I would say let the exception bubble up the stack. If you really want to define the contract and control some of the implementation (such as error handling) then you should make a base class (I would lean towards a MustInherit/Abstract class in this situation) with MustOverride Methods that the base class calls from its methods (in your situation in a Try Catch so you can do your special error handling).

阅读全文

相关推荐

最新文章