正如标题所说:记录接口的抛出异常是一种好习惯吗?是否存在普遍认可的最佳实践?我觉得这是一个实现细节,不应该以任何方式包含在界面中,但同时我觉得界面的用户应该有这些宝贵的信息。
这样的评论是否是一个好的做法是另一个讨论的主题,所以为了限制这个问题的范围,我们假设我们已经同意用这样的评论记录代码是一个好习惯。这里有'像这样的评论'我的意思是你可以从文件或元数据中生成东西,而不仅仅是'正常'评论。示例包括XML文档,Javadoc和Doxygen。
现在,如果有任何最佳实践甚至可以达成一致,那么这些C#示例中的哪一个是更好的做法?
无异常文档的界面:
public interface IMyInterface {
/// <summary>
/// Does something.
/// </summary>
void DoSomething();
}
与异常文档的接口:
public interface IMyInterface {
/// <summary>
/// Does something.
/// </summary>
/// <exception cref="System.Exception">Something went wrong.</exception>
void DoSomething();
}
答案 0 :(得分:10)
接口是契约,如果该合同的一部分包含抛出异常的情况,那么您肯定应该将其包含在您的文档中。您可以看到整个.NET框架中的接口中记录的异常示例,例如IEnumerator
有很多。 (通过右键单击IEnumerator
的声明并导航到&#34;元数据视图&#34;来检索文本。
public interface IEnumerator
{
/// <summary>
/// Advances the enumerator to the next element of the collection.
/// </summary>
///
/// <returns>
/// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.
/// </returns>
/// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created. </exception><filterpriority>2</filterpriority>
bool MoveNext();
/// <summary>
/// Sets the enumerator to its initial position, which is before the first element in the collection.
/// </summary>
/// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created. </exception><filterpriority>2</filterpriority>
void Reset();
/// <summary>
/// Gets the current element in the collection.
/// </summary>
///
/// <returns>
/// The current element in the collection.
/// </returns>
/// <filterpriority>2</filterpriority>
object Current { get; }
}
答案 1 :(得分:3)
接口仅定义要执行的操作的合同,而不是它们的实现方式。请考虑以下示例:
void Sort(SortOrder order);
您可能想要添加throws ArgumentNullException if order is null
注释,但如果接口的实现者决定在SortOrder
上接收空值意味着它应该使用默认SortOrder
会发生什么? (错误的决定,但可能的决定)。对于实现接口的人来说,这应该是一个有效的决定,如果它不是决定这样的事情的选项,那么你应该提供一个抛出异常而不是接口的抽象基类。
向接口添加例外就像使接口继承自IDisposable接口一样。这些是不应该进入接口定义的实现细节。