43

为什么在 .NET 4.5中List<T>实现?IReadOnlyList<T>

List<T>不是只读...

4

7 回答 7

47

因为List<T>实现了所有必要的方法/属性/等。(然后是一些)的IReadOnlyList<T>。接口是一个契约,上面写着“我至少可以做这些事情”。

的文档IReadOnlyList<T>说它代表一个只读的元素集合。

这是正确的。该接口中没有 mutator 方法。这就是只读的意思,对吧?IReadOnlyList<T>以“典型”(合同)方式使用,而不是作为标记

于 2013-03-07T04:18:10.540 回答
27

接口仅描述将要实现的功能。它没有描述不会实现的功能。因此,IReadOnlyList 是一个不正确的接口名称,因为它不能规定不会写入写入功能。

描述您可以读取列表内容的方法/功能。该接口应该是 IReadableList 而不是 IReadOnlyList。

于 2014-09-05T09:35:50.273 回答
6

实现一个接口与“标记”它不同。List<T>也实现IEnumerable<T>了,但这并不意味着您仅限于简单地枚举它。

他们为 API 创建添加了只读接口,而不是这样你就可以用接口标记你的只读类型。IReadOnlyCollection<T>当我只想知道集合中元素的数量而不枚举它时,或者IReadOnlyList<T>当我需要通过索引引用集合中的元素时,它允许我使用参数。这对每个人都有好处——我可以具体说明我的调用者需要什么,同时允许我的调用者使用他想要的任何集合类型,只要它符合我通过参数类型设置的最低标准。

所以我认为更困难的问题是,你为什么List<T>实施IReadOnlyList<T>

于 2013-08-02T23:30:53.413 回答
5

它实现接口的事实并不意味着它是只读的。但是因为它实现了接口,您现在可以将它传递给期望IReadOnlyList<T>. 所以看待它的方式是,它实现了只读列表接口......以及一些写入方法。

于 2013-03-07T04:21:04.807 回答
2

接口IReadOnlyListIReadOnlyCollection有点令人困惑,因为它们并不意味着集合是只读的,只是支持只读访问。从MSDN 文档(向下滚动到备注)

列表元素的内容不保证是只读的。

更好的名称是IReadable,请参阅Why does not generic ICollectionimplement IReadOnlyCollectionin .NET 4.5? . 此外,这意味着IList应该继承,IReadOnlyList尽管它不是由于向后兼容性,请参阅为什么不IList<T>继承自IReadOnlyList<T>.

于 2016-10-16T11:13:07.310 回答
1

IReadOnlyList 是“引用不变性”概念的替代品,该概念在 C++ 中找到,但在 C# 中没有。C++ 等价物是:

无效函数(T const* t){...}

或完全等效,因为有些人更喜欢:

无效函数(常量 T* t){...}

它表示函数 func 不会改变其参数 t 引用的对象,称为 t 的“所指对象”。它没有说明任何其他代码是否会改变 t 的所指对象,甚至可以。

因此,C# 接口是编译器构造的替代品。为什么 C# 没有引用不变性的概念是一个历史问题:我认为这是一个错误,但现在修复它为时已晚。我认为提供接口替代品很好。多年来,我一直在使用与 IReadOnlyList<> 完全相同的接口,幸运的是使用了另一个名称 IConstList<>。我可以用 IReadOnlyList<> 代替我对 IConstList<> 的使用。

于 2015-03-07T22:35:57.403 回答
0

运行 IReadOnlyList(Of T) 调用实现该接口的对象的代码通常运行相同的执行线程,这不是真的吗?这可以防止对象自行更改,除非它在不同的执行线程上运行,但对于这种情况,我们有同步调用来解决这个问题。

于 2016-06-05T12:24:16.717 回答