List <t> .AsReadOnly()vs IReadOnlyCollection <t> </t> </t>

时间:2013-07-01 06:18:52

标签: c# generics collections

List<T>实现IReadOnlyCollection<T>接口并提供AsReadOnly()方法,该方法返回ReadOnlyCollection<T>(后者实现IReadOnlyCollection<T>)。

AsReadyOnly()的用法/原因是什么?它的存在气味有一两个边缘情况,只需将列表作为IReadOnlyCollection<T>返回就不够好了。

起初我可能会阻止投入成本,但看起来你可以使用ReadOnlyCollection<T>的{​​{1}}访问者来做到这一点。

顺便说一句。 Items类型的文档读取

  

提供通用只读集合的​​基类。

在我的脑海中,与描述为

的构造函数冲突
  

初始化(...)类的新实例,它是指定列表周围的只读包装。

更新 我没有看到ReadOnlyCollection<T>的{​​{1}}受到保护。

2 个答案:

答案 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>.KeysDictionary<K,V>.Values之类的内容。这适用于消费者不能在生产者可以改变内容的情况。它与Collection<T>协同工作,为所有者提供钩子,以便在添加项目时验证更改或执行副作用。

另一方面,

IReadOnlyList<T>只是一个提供集合的只读视图的接口。方法可以使用它来说“我需要一个随机访问集合,但我不需要能够修改它”。例如,BinarySearch方法可能如下所示:

public int BinarySearch<T>(IReadOnlyList<T> list, int start, int length);

为了使这个方法有用,需要能够传入任何List。强制创建包装器集合将非常昂贵。