List<T>
实现IReadOnlyCollection<T>
接口并提供AsReadOnly()
方法,该方法返回ReadOnlyCollection<T>
(后者实现IReadOnlyCollection<T>
)。
AsReadyOnly()
的用法/原因是什么?它的存在气味有一两个边缘情况,只需将列表作为IReadOnlyCollection<T>
返回就不够好了。
起初我可能会阻止投入成本,但看起来你可以使用ReadOnlyCollection<T>
的{{1}}访问者来做到这一点。
顺便说一句。 Items
类型的文档读取
提供通用只读集合的基类。
在我的脑海中,与描述为
的构造函数冲突初始化(...)类的新实例,它是指定列表周围的只读包装。
更新
我没有看到ReadOnlyCollection<T>
的{{1}}受到保护。
答案 0 :(得分:44)
如果您只是将实际List<T>
作为IReadOnlyList<T>
返回,则调用者可以随时将其强制转换,然后根据需要修改列表。相反,调用AsReadOnly()
会创建列表的只读包装,消费者无法更新。
请注意,只读包装器将反映对基础列表所做的更改,因此访问原始列表的代码仍然可以更新它,并且知道只读版本的任何使用者都将看到这些更改。
答案 1 :(得分:20)
首先,不是AsReadOnly()
被添加,因为IReadOnlyList<T>
不够好 - IReadOnlyList<T>
仅在.NET 4.5开始时可用AsReadOnly()
方法存在从.NET 2开始。
更重要的是:AsReadOnly()
和IReadOnlyList<T>
的用途非常不同。
ReadOnlyCollection<T>
用于实现对象模型,例如Dictionary<K,V>.Keys
和Dictionary<K,V>.Values
之类的内容。这适用于消费者不能在生产者可以改变内容的情况。它与Collection<T>
协同工作,为所有者提供钩子,以便在添加项目时验证更改或执行副作用。
IReadOnlyList<T>
只是一个提供集合的只读视图的接口。方法可以使用它来说“我需要一个随机访问集合,但我不需要能够修改它”。例如,BinarySearch
方法可能如下所示:
public int BinarySearch<T>(IReadOnlyList<T> list, int start, int length);
为了使这个方法有用,需要能够传入任何List。强制创建包装器集合将非常昂贵。