为什么List <t> .IndexOf(T)不返回可为空的int?</t>是否有实际原因?

时间:2012-06-02 18:42:27

标签: c# list nullable

方法List<T>.IndexOf()返回the zero-based index of the first occurrence of item within the entire List, if found; otherwise, –1

我在Code Complete之间看到了一个平行线,我告诉我要“避免隐藏含义的变量”。

  

例如:   中的价值   变量pageCount可能表示打印的页数,除非   它等于-1,在这种情况下它表示发生了错误。

好吧,我不知道这个含义是否“隐藏”,因为它的记录足够清楚,但 null 似乎比 -1 更能传达给我的意义。 ,.HasValue读取比&gt;更好的检查-1 即可。据我所知,List和Nullable类型都是在C#2.0中引入的,所以我不认为重新调整int的原因与向后兼容性有关。所以,你知道是否有原因,或者这是否是某人忘记实施的事情,我们现在必须永远忍受这个错误?

6 个答案:

答案 0 :(得分:10)

List以2.0版本的运行时发布,因为它是可空的T.但是List实现了IList,它存在于运行时的1.0版本中,它不仅没有可空,它不支持泛型。为了满足IList接口的约定,实现者必须在失败索引上返回-1。代码完成还认为您必须满足您同意的合同,因此List.Indexof必须返回-1。


回答评论:

到具有泛型的2.0运行时,已经有数千个针对非泛型版本编写的应用程序。通过支持通用接口作为非通用接口的扩展,可以最有效地迁移该代码。此外,图像必须具有相同名称和90%相同用途的类,但在几种方法的情况下完全不同的语义。

答案 1 :(得分:6)

System.Collections.Generic.List可能已经在.NET 2.0中引入,并且可以为空,但是-1的使用早于它。列表框的ArrayList.IndexOf()Array.IndexOf()String.IndexOf()SelectedIndex等等。因此List<T>最有可能与现有库保持一致。 (事实上​​即使是经典的VB也有这个含义,所以它甚至早于.NET 1.0)

正如@rerun指出的那样,它不仅仅是风格的一致性,它实际上是界面合同的一部分。所以给他+1。

虽然List<T>没有跟随ArrayList的脚步而没有实现IList,但这样做对于那些已经熟悉这些的程序员来说更有用了

答案 2 :(得分:2)

只是一个猜测,但我认为这与历史原因和可读性有关。尽管-1是“特殊值”,但在任何其他情况下都不会返回。在我看来,你引用的规则主要是为了避免返回可能具有多个含义的值。 -1是c ++和类似语言的标准,因此它已成为跨语言的一种习惯用语。此外,尽管hasvalue可能更具可读性,但我认为最好在整个框架中保持相同的样式,这需要从头开始。最后,恕我直言,在我有限的经验中,因为为了在其他地方使用它们而必须打开可装空的类型,它们可能比它们的价值更麻烦,但那只是我。

答案 3 :(得分:1)

我认为这是为了向后兼容,就像在框架1.1中那样,没有任何问题,并且当时创建了API。

答案 4 :(得分:1)

原因可能是一个简单的事实:Nullable<T>(写T?时使用的实际类型)涉及索引搜索之类的简单复杂性。 T? x x == null x.HasValue实际上只是null的语法糖,当它结果不是x.Value时,你仍然必须通过{{1}访问实际值}。

与仅返回负值相比,你并没有真正获得任何东西,这也不是一个有效的指数。事实上,你让事情变得更加复杂。

答案 5 :(得分:0)

它遵循与String.IndexOf相同的模式,以及IndexOf方法的许多其他实现和变体,而不仅仅是在.NET库中。

使用-1作为返回值是一个幻数,通常应避免使用。但是,这种模式是众所周知的,当您实现库方法时,这显然是一个优势。