为什么List<T>
在.NET 4.5中实现IReadOnlyList<T>
?
List<T>
不是只读的......
答案 0 :(得分:40)
因为List<T>
实现了所有必要的方法/属性/等。 {和} IReadOnlyList<T>
。界面是一份合同,上面写着“我至少可以 这些东西。”
IReadOnlyList<T>
的文档说它代表了一个只读的元素集合。
没错。该接口中没有mutator方法。这就是只读的意思,对吗? IReadOnlyList<T>
以“典型”(合同)方式使用,而不是marker。
答案 1 :(得分:23)
接口仅描述将要实现的功能。它没有描述不会实现的功能。因此,IReadOnlyList是一个不正确的接口名称,因为它不能指示不会写入写入功能。
描述的方法/功能可以读取列表的内容。接口应该是IReadableList而不是IReadOnlyList。
答案 2 :(得分:5)
它实现接口的事实并不意味着它是只读的。但是因为它实现了接口,所以现在可以将它传递给期望IReadOnlyList<T>
的方法。因此,查看它的方法是,它实现了只读列表接口......以及一些写入方法。
答案 3 :(得分:5)
实现接口与“标记”不同。 List<T>
也实现IEnumerable<T>
,但这并不意味着您只能枚举它。
他们添加了用于创建API的只读接口,而不是使用接口标记只读类型。当我只想知道集合中元素的数量而不枚举它时,它允许我使用IReadOnlyCollection<T>
作为参数,或者当我需要通过索引引用集合中的元素时,IReadOnlyList<T>
。这对每个人都有好处 - 我可以具体说明我的调用者需要什么,同时允许我的调用者使用他想要的任何集合类型,只要它符合我通过参数类型设置的最低标准。
所以我认为更难的问题是,为什么不会你List<T>
实施IReadOnlyList<T>
?
答案 4 :(得分:1)
IReadOnlyList是&#34;引用不变性&#34;的概念的替代品,在C ++中找到但在C#中找不到。 C ++等价物是:
void func(T const * t){...}
或完全等同,有些人更喜欢:
void func(const T * t){...}
它表示函数func不会改变其参数引用的对象,称为&#34; referent&#34; of。它没有说明任何其他代码是否会改变t的指示物,甚至可以。
因此C#接口是编译器构造的替代品。为什么C#没有引用不变性的概念是一个历史问题:我认为这是一个错误,但现在修复它为时已晚。我认为提供接口替代是好的。我一直在使用与IReadOnlyList&lt;&gt;完全相同的界面多年来,幸运的是有另一个名字,IConstList&lt;&gt;。我可以替换我对IConstList的使用&lt;&gt;使用IReadOnlyList&lt;&gt;。
答案 5 :(得分:1)
接口IReadOnlyList
和IReadOnlyCollection
有点令人困惑,因为它们并不意味着集合是只读的,只是支持只读访问。从MSDN documentation(向下滚动到备注)
列表元素的内容不保证是只读的。
更好的名称是IReadable
,请参阅Why doesn't generic ICollection
implement IReadOnlyCollection
in .NET 4.5?。此外,这意味着IList
应该继承IReadOnlyList
,尽管它不是由于向后兼容性,请参阅Why doesn't IList<T>
inherit from IReadOnlyList<T>
?。
答案 6 :(得分:0)
运行IReadOnlyList(Of T)的代码调用实现该接口的对象通常运行相同的执行线程是不是真的。这可以防止对象被自己更改,除非它在不同的执行线程上运行,但是对于那种情况,我们有同步调用来解决它。