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

问题描述 投票:0回答:7

为什么

List<T>
在.NET 4.5中实现
IReadOnlyList<T>

List<T>
不是只读...

.net .net-4.5 base-class-library
7个回答
54
投票

因为

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

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

没错。该接口中没有修改器方法。这就是只读的意思,对吗?

IReadOnlyList<T>
以“典型”(合同)方式使用,而不是作为 标记


34
投票

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

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


7
投票

实现接口与“标记”它不同。

List<T>
还实现了
IEnumerable<T>
,但这并不意味着您只能简单地枚举它。

他们添加了用于 API 创建的只读接口,而不是让您可以用接口标记只读类型。当我只想知道集合中元素的数量而不枚举它时,它允许我使用

IReadOnlyCollection<T>
作为参数,或者当我需要通过索引引用集合中的元素时使用
IReadOnlyList<T>
。这对每个人都有好处——我可以具体说明我需要调用者提供什么,同时允许调用者使用他想要的任何集合类型,只要它满足我通过参数类型设置的最低标准即可。

所以我认为更困难的问题是,为什么不会你有

List<T>
实施
IReadOnlyList<T>


6
投票

它实现接口的事实并不意味着它是只读的。但因为它实现了接口,所以您现在可以将其传递给需要

IReadOnlyList<T>
的方法。所以看待它的方法是,它实现了只读列表接口......以及一些写入方法。


5
投票

接口

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

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

更好的名称是

IReadable
,请参阅为什么泛型
ICollection
在 .NET 4.5 中不实现
IReadOnlyCollection
。此外,这意味着
IList
应该继承
IReadOnlyList
,尽管它不是由于向后兼容性,请参阅 为什么
IList<T>
不继承
IReadOnlyList<T>


1
投票

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

void func(T const* t) {...}

或者完全等同,正如有些人喜欢的那样:

void func(const T* t) {...}

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

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


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.