.NET 4.0中的只读列表或不可修改列表


100

据我所知,.NET 4.0仍然缺少只读列表。为什么框架仍然缺少此功能?这不是领域驱动设计最常见的功能之一吗?

Java与C#相比具有的少数优点之一是以Collections.unmodifiablelist(list)的形式呈现的方法,在IList <T>或List <T>中似乎早该这样做了。

使用IEnumerable<T>是解决问题的最简单方法- ToList可以使用并返回副本。


似乎拥有真正的只读的唯一真实方法List<T>是编写自己的只读文件,据我所知,没有内置的类支持List<T>开箱即用的所有“只读”功能,如ContainsLINQ查询等。
jrh

Answers:


146

您正在寻找的ReadOnlyCollection,.NET2以来一直存在。

IList<string> foo = ...;
// ...
ReadOnlyCollection<string> bar = new ReadOnlyCollection<string>(foo);

要么

List<string> foo = ...;
// ...
ReadOnlyCollection<string> bar = foo.AsReadOnly();

这将创建一个只读视图,该视图反映对包装的集合所做的更改。


1
我觉得自己问了一个有点傻了这个问题,现在-不知道关于ReadOnlyCollection
克里斯小号

54
不会-当我去寻找相同的东西并找到您的问题时,我也没有
Roland Tepp

9
那是一个令人讨厌的类。它位于System.Collections.ObjectModel命名空间中,而不是我希望在其中找到的System.Collections.Generic。我想是因为那是通用名称空间存在之前的位置。我仍然希望基类保留在ObjectModel中,而泛型类将添加到Generic中。我想他们有他们的理由,但是我觉得很烦。
BlueMonkMN 2012年

5
@BlueMonkMN:请参阅本文以了解为什么它与Collections.Generic命名空间分开。
Uchitha

7
但这不是列表,而是集合。因此,如果使用它,则需要修改所有代码以使用Collection而不是List。
罗曼·扎比奇



11

如果列表的最常见模式是遍历所有元素,IEnumerable<T>或者IQueryable<T>也可以有效地充当只读列表。


4
如果将List公开为IEnumerable,则使用者可以简单地将其投射回List并进行修改。
JulianR

4
当然,但这并不是防弹措施-您也可以阅读私有字段并查找原始列表。它更多地描述了保持只读状态的意图。
安娜·贝茨

5
你不是通过调用修改原始列表ToList()或者,只是一个副本
克里斯小号

请注意,IEnumerable它不是“只读”方法的完整集合,例如,它不包含之类的方法Contains
jrh

8

在2.0中,您可以调用AsReadOnly获取列表的只读版本。或将现有对象包装IListReadOnlyCollection<T>对象中。


这相当于我
克里斯S

我在.NET 4中错过了此功能,因为我使用的是IList <T>而不是真正的List <T>。确保注意,只要您处理List <T>,AsReadOnly在.NET 4中仍然可用。
BlueMonkMN 2012年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.