为什么Array类明确实现IList接口而不是隐式实现?

4
我的目标语言是C#和.NET框架。我想知道这个主题背后的重点或原因是什么?
非常感谢任何建议和建议。
编辑
我为什么问这个问题? 因为现在,一些Array类的有用成员(如索引)被隐藏在转换后面!!! 我想知道如果微软分割ilist接口会不会更好?

2
我已将“c#”标签更改为“.net”,因为这不是特定于语言的;这是在BCL中做出的决策,而不是在语言层面上。 - Jon Skeet
Array.IndexOf() 不需要强制转换。如果你真正的问题是“为什么它是一个静态方法”,那么答案在这里:https://dev59.com/emw15IYBdhLWcg3wSJvQ#6714318 - Hans Passant
首先,我想说在 System.Array 类上调用静态方法是很丑陋的。无论如何,您可以通过显式转换访问 IList 接口成员的索引,并通过任何数组进行访问。例如:((IList)myArray).indexof(ourValue)。正如您所看到的,我们需要一个显式转换,这并不是很好看。 - siamak
1个回答

6
值得一提的是,你不需要隐式或显式地实现整个接口 - 这是逐成员决定的... 我猜测不同的成员会有不同的原因。我只是猜测(很少有人能在这里给出明确的答案),但可能的原因如下:
- Count:我怀疑当您处理特定的数组类型时,Length属性具有特殊支持(我没有检查IL)并且更有效率;将两个都呈现给开发人员是不好的。 - IsFixedSize:如果您知道正在处理一个数组,则知道大小是固定的。 - IsReadOnly:如果您知道正在处理一个数组,则知道它是可变的。 - IsSynchronized:如果您知道正在处理一个数组,则知道它未同步。 - Item:非泛型IList接口将公开接受/返回对象的索引器;特定类型的数组索引器更加类型安全(而且可能直接获得支持)。Array中的访问器方法提供了具有不等于1的秩的数组的选项。 - SyncRoot:数组永远没有SyncRoot。 - Add、Insert、Remove、RemoveAt、Clear:您永远无法更改数组的大小,因此这些都不适用。
换句话说,如果您已经拥有编译时信息,说明这是一个数组,那么您已经知道答案或绝对无法使用这些操作 - 或者有更好的方法来做到这一点。
可能合理的是:
- Contains、CopyTo、IndexOf:这些都可以通过隐式接口实现来公开。我不知道为什么没有。 - GetEnumerator(来自IEnumerable)已经通过隐式接口实现公开了。

很高兴见到你。谢谢,正如你所提到的,我们可以说至少有一个原因是为了隐藏一些我们不希望其他用户访问的成员,例如:添加、插入、删除,如果他们尝试使用对IList的引用来访问它们,我们将抛出“NotSupportedException”,因此从设计角度来看,隐藏可能是一个目的。我是正确的吗? - siamak
@siamak:它的隐藏是为了试图阻止人们调用永远不合适的方法。 - Jon Skeet
@Jon Skeet:我认为你回答中最美妙的部分是“这是一个逐成员的决定”。这对于开发人员来说是非常重要的一点,需要注意。谢谢。 - siamak
1
我可能希望存在"IsReadOnly",以便将来微软可能决定让Array派生自ReadableArray,这将有另一个后代类ImmutableArray。只需要对数组进行读取访问但不关心它是否是不可变的代码可以接受类型为ReadableArray的参数。为了使这种模式起作用,ReadableArray应该有一个"IsReadOnly"成员;作为该类的派生类,Array也应该有。 - supercat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接