IList<T 的 IndexOutOfRangeException>

IndexOutOfRangeException for an IList<T>

提问人:Hosam Aly 提问时间:12/20/2008 更新时间:12/21/2008 访问量:599

问:

我正在实现一个列表,我想知道 IndexOutOfRange 的定义。您认为以下哪一项更好?

/// <exception cref="IndexOutOfRangeException">if index is less than 0
/// or greater than <see cref="Count"/>
public T this[int index] { get { return myArray[index]; } }

/// <exception cref="IndexOutOfRangeException">if index outside the valid range
/// for an array of length equal to <see cref="Count"/></exception>
public T this[int index] { get { return myArray[index]; } }

我正在考虑从索引从 1 开始的数组的 .NET 语言中使用此类的情况。我对这个话题了解不多,但第二个版本无论如何都比第一个版本好吗?

.NET 数组异常

评论


答:

0赞 user44484 12/20/2008 #1

您是否也可以拥有“Base”属性,然后您可以说:

/// <exception cref="IndexOutOfRangeException">if index is less than <see cref="Base" />

如果你不能有 Base 属性,那么第二个版本会更好,如果你必须小心从 1 开始的数组。

1赞 Dan Vinton 12/20/2008 #2

稍微OT:你能封装一个列表而不是一个数组,然后一切都在洗涤中消失,因为封装的列表会产生适当的异常吗?

编辑:如果你真的在内部需要数组,如何先将其包装在访问器内的列表中,然后按索引选择。这样,从列表索引到数组索引的转换发生在组件的语言内部,而不是调用方的语言内部。

据推测,列表索引的语义不会在 .Net 语言之间改变?这是您的组件应该遵循的内容,因为它实现了列表接口。

再次编辑:实际上,这有问题吗?

人们通过访问器访问您的数组,该访问器是用您控制的语言编写的,因此知道数组索引从哪里开始。即使你从 VB.Net 调用方调用你的(比如)C#类,访问器仍然会使用C#的数组索引思想,不是吗?

评论

0赞 Hosam Aly 12/20/2008
感谢您的建议,但我希望通过直接使用数组来获得更好的性能。
0赞 Dan Vinton 12/20/2008
您确定需要优化吗?
0赞 Hosam Aly 12/20/2008
我忘了提到,我还需要处理线程之间的一些同步。
0赞 Hosam Aly 12/20/2008
感谢您的编辑。这看起来是个好主意,只不过它会导致很大的性能开销。谢谢你的帮助!
0赞 Rob Kennedy 12/21/2008
丹,你是对的。对于具有不同数组基数的语言来说,绝对没有问题,除非他还希望他的类的数组索引运算符的行为与调用语言的行为相同。但我认为尝试这样做不是一个好主意。
0赞 tvanfosson 12/20/2008 #3

IList<T> 已记录异常 (ArgumentOutOfRangeException,而不是 IndexOutOfRangeException) 。如果您正在实现接口而不更改记录的行为,为什么需要记录它?如果你要记录它,它应该与界面一致。

编辑:刚刚注意到您的实现(或者至少通过命名您的实现的含义)。我同意@Dan,你真的应该基于 List<T> 而不是数组,以便实现与接口一致。在这种情况下,无需重新记录异常。如果不更改基础实现,则应捕获 IndexOutOfRangeException 并将其映射到接口记录的 ArgumentOutOfRangeException。

评论

0赞 Hosam Aly 12/20/2008
实际上,我正在将记录的行为更改为更简单的行为,这使得代码更简单、更快速,并且足以满足我的需求。(说实话,我从来不认为索引器应该抛出除 IndexOutOfRangeException 以外的任何异常,除非出于调试目的。
0赞 Hosam Aly 12/20/2008
我的问题更多的是关于这个案子是否会发生。考虑我会做一个检查。我应该写“if (index < 0)”还是“if (index < myArray.GetLowerBound(0)”?
0赞 Marc Gravell 12/20/2008 #4

顺便说一句 - 你总是可以简单地继承作为起点......这提供了原始代码,同时允许您自定义内容。您可以从 继承,但与 上没有有用的方法不同。Collection<T>List<T>Collection<T>virtualList<T>

评论

0赞 Hosam Aly 12/20/2008
谢谢你的建议;我不知道这门课。但是,我认为我需要对我的集合进行更精细的控制,因为我需要处理一些并发问题。