创建可能抛出IndexOutOfRangeException的属性

时间:2012-06-22 17:05:04

标签: c# api-design

我有一个包含项目集合的类。为方便起见,我提供了由

实现的GetCurrentItem
public Type GetCurrentItem
{
     get { return this.items[this.items.Count - 1]; }  
}

如果列表中没有项目,则会抛出异常。

我应该抛出异常还是应该返回null?如果这是我递给你的API,你会期待什么?例外还是null?有没有更好的方法来处理这个?

7 个答案:

答案 0 :(得分:9)

哪个更正确?正如柯克的评论所暗示的那样:这取决于。有时null具有逻辑意义,如果没有默认值是合理的,有时异常更适合。我尝试做的一件事是想“正在调用GetCurrentItem是一个逻辑上的失败还是一个安全的事情?”

如果在没有时调用GetCurrentItem失败,则抛出异常是正确的过程。例如,如果您的集合具有HasCurrentIsEmpty属性,有人可以在调用GetCurrentItem之前检查结果,那么他们应该“知道更好”。但是,如果当前项目null是使用您的类的正确逻辑方式,那么无论如何都要设计它。无论哪种方式,我都会记录代码注释中的行为,以便让用户知道预期的行为。

我会说这个,但是暴露ArgumentOutOfRange异常可能会泄露实现细节。也就是说,如果这个类的用户不知道内部结构是一个数组或List<T>,那么不要流出那个异常,但抓住它,包装它,并抛出一个更有意义的异常(custom) ,或类似InvalidOperationException)。

由于他们并没有真正直接传递参数,因此获得ArgumentOutOfRange异常可能会引起混淆: - )

答案 1 :(得分:3)

让它抛出一个错误。这就是其他收藏品的工作方式。应该由用户应用程序来处理潜在的异常(特别是在使用集合时)。应该有一个bool HasSelection()方法,用户可以在继续之前调用该方法。

答案 2 :(得分:3)

特殊情况应使用例外情况。如果CurrentItem可以为null,则不应抛出异常。我不明白为什么没有一个CurrentItem是例外。

答案 3 :(得分:1)

那么问题是你是否期望GetCurrentItem返回一个安全值。如果Type是可空的,那么当没有当前项时,GetCurrentItem可能应该返回null。如果您总是希望列表非空,并且默认情况下总是选择某些内容,那么抛出一个有意义的异常。

除非您的案例确实是例外而不是正常的用例,否则您通常不应抛出异常。但是,这可能是相当主观的。

答案 4 :(得分:1)

我尝试从用户的角度考虑它。转到Principal of Least Astonishment

如果我使用的是库或对象并且调用了GetCurrentItem并且抛出了IndexOutOfRangeException,我会想,“我没有用索引调用任何东西,我想要当前的项目。”因此,我的建议是返回null,这会让我想到,“哦,没有当前的项目。”

或者,如果该属性是索引器并且我想获得某个索引的项目,我不会对IndexOutOfRangeException感到惊讶。

答案 5 :(得分:0)

如果此GetCurrentItem对您的API有意义,那么当没有项目时我会抛出“InvalidOperationException”。如果允许null作为有效结果,您可能希望以不同的名称命名。

考虑现有的LINQ Last方法是否已提供相同的功能。

答案 6 :(得分:0)

如有疑问,请关注.NET。此功能类似于List.Last(),如果为空则抛出异常。

http://msdn.microsoft.com/en-us/library/bb358775