如何指定接口的实现者抛出的异常?
我目前正在开发一个解决方案,并以一种能够强烈实现策略/提供商模式的方式对其进行设计。因此,该解决方案公开了许多接口并包含这些接口的默认实现,这些接口可以通过 DI 类型方法进行替换。
当主机应用程序使用许多这样的接口时,它期望处理可能发生的某些异常,例如 IDataRetriever
接口有一个方法 SomeDataType GetData(int timeout);
和主机可以处理一些自定义异常,例如 DataRetrievalTimeoutException 或 NetworkConnectionException。
我的问题是,标记接口类的最佳方法是什么,以便当开发人员实现它时,他们会知道应该抛出某些异常并由主机处理?
目前,我刚刚将异常 xml 标记添加到方法 xml 注释中 - 这是否足够?
I'm currently developing a solution and have designed it in a way such that it strongly implements the strategy/provider pattern. As such the solution exposes a number of interfaces and contains default implementations of these interfaces which can be replaced via a DI type methodology.
Where the host application uses a number of these interfaces it is expecting to handle certain exceptions that may occur, for example IDataRetriever
interface has a method SomeDataType GetData(int timeout);
and the host can handle some custom exceptions such as DataRetrievalTimeoutException
or NetworkConnectionException
.
My question is, what is the best way to mark up the interface class such that when a developer implements it they would know that certain exceptions should be thrown and would be handled by the host?
At the moment I have just added the exception xml tags to the methods xml comment - does this suffice?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
XML 标记(以及您想要编写的任何其他文档)基本上是目前在“vanilla”.NET 中最接近的标记。
您可能需要查看代码契约,它可以让您使用契约注释您的界面,其中可以包括异常、先决条件ETC。
The XML tags (and any other documentation you want to write) are basically the closest you've got in "vanilla" .NET at the moment.
You might want to look at Code Contracts which lets you annotate your interface with contracts, which can include exceptions, preconditions etc.
您不能在界面中。你可以在基类中。
与
You cannot in an interface. You CAN in a base class.
vs.
我建议在接口中定义异常类,并指定不从这些异常派生的任何异常都不应被允许逃逸,除非 CPU 着火或存在其他此类严重情况(即使如此,有一个显式定义的 IWoozle.SystemCorruptionException ,这样如果 Pokemon 处理程序只是捕获、记录并抛出异常,日志将反映出至少有人认为该异常很重要)。
我认为 Microsoft 建议避免定义自定义异常类型是不幸的,因为这意味着没有干净的方法来区分
IEnumerator.MoveNext()
是否抛出InvalidOperationException
因为底层集合在枚举期间发生了更改,或者IEnumerator.MoveNext()
的内部处理是否遇到InvalidOperationException
并简单地让它冒泡到调用方。相反,如果IEnumerator.MoveNext()
在前一种情况下抛出IEnumerator.InvalidatedEnumeratorException
,则任何转义的InvalidOperationException
都必须代表后一种情况。I would suggest defining exception classes within the interface, and specifying that no exceptions which do not derive from those should be allowed to escape unless the CPU is on fire or other such drastic situation exists (even then, it might not be a bad idea to have an explicitly-defined
IWoozle.SystemCorruptionException
so that if a Pokemon handler simply catches, logs, and throws out the exception, the log will reflect that at least someone thought the exception was important).I consider Microsoft's recommendation to avoid defining custom exception types to be unfortunate, since it means that there's no clean way to distinguish whether
IEnumerator<T>.MoveNext()
throws anInvalidOperationException
because the underlying collection was altered during enumeration, or whether the internal processing ofIEnumerator<T>.MoveNext()
encounters anInvalidOperationException
and simply lets it bubble up to the caller. If instead,IEnumerator<T>.MoveNext()
threw anIEnumerator.InvalidatedEnumeratorException
in the former case, then anyInvalidOperationException
which escaped would have to represent the latter case.这不应该由实现该接口的类决定吗?
例如,如果我采用您的接口并使用 GetData 方法实现我自己的类,我可以从任何地方“获取”数据。假设它是一个 Web 服务,那么可能抛出的异常类型可能与我从本地文件系统“获取”数据时抛出的异常类型不同。
因此,在我的实现中,我将实现(并记录)特定于实现的那些异常,以便使用该实现的任何代码都可以处理它们。如何处理这些异常可能非常具体于实现,假设我在 Web 应用程序而不是桌面应用程序中使用它们。
Should this not be up to whatever class implements the Interface?
Eg if I take your Interface and implement my own class, with a method GetData, I could be 'getting' data from anywhere. Lets say it was a web service then the types of exceptions that could be thrown could be different to those if I was 'getting' data from local file system.
So in my implementation I would implement (and document) those exceptions specific to the implmentation so that whatever code is using the implementation could handle them. How those exception are handled may be very specific to the implementation, say I am consuming them in a web app as opposed to a desktop app.
我认为提供此信息的最佳方法是在为每个接口提供的 XML 文档中。在那里,您可以指定该方法抛出什么异常,以便主机可以处理该错误。
I think the best way to provide this information is in the XML documentation that you would provide for each interface. There you can specify what Exception is thrown by the method so that the host can handle that error.
如果您不能支持通用基类,另一种策略是扩展方法实现。
这样做的好处是允许您不需要继承链。
Another strategy if you can't support a generic base class, is extension method implementations.
This has the benefit of allowing you to not require an inheritance chain.