【问题标题】:Read-only list that guarantees not modyfing underyling collection保证不修改底层集合的只读列表
【发布时间】:2015-11-09 14:20:32
【问题描述】:

.net 中是否有任何类与IReadOnlyList 类似,但它包含所有项目的内部副本?如果有东西返回IReadOnlyList,就不能保证底层集合不会被修改?...

编辑:

来自文档:

ReadOnlyCollection<T> 泛型类的实例总是 只读。只读集合只是一个集合 防止修改集合的包装器; 因此,如果 对基础集合进行更改,只读 集合 == 反映 == 那些变化

所以它不是真正的只读。

EDIT2:

我需要只读数组之类的东西。

例如:

public class ReadOnlyArray<T> : IEnumerable<T>, ...
{
    public ReadOnlyArray (IEnumerable<T> items)
    {
          internalItems = createCopy (items);
    }
}

现在当我看到这样的代码时:ReadOnlyArray x = GetDataFrom3rdAPI();

我是 100% 我不仅收到只读对象,而且不可能 在代码中的其他地方修改基础集合。班级类型应该说它给了我那种安慰。

使用 ReadOnlyCollection,它说只有我可以阅读,但我无法控制底层集合 - 我不知道在第 3 个 API 代码中的其他地方是否有任何对底层集合的引用。

EDIT3:

当我说不应该修改底层集合时,我的想法是集合中的所有项目(所有引用)都应该始终指向同一个实例。然而,这些实例本身可以是可变的。

所以当我遍历这个集合时,我总是在迭代相同的实例。

【问题讨论】:

  • @zgnilec 你遇到过不可变集合吗?
  • @AdamHouldsworth:什么?我需要明确知道无法更改基础集合。所以我认为我需要为自己创建课程。
  • @zgnilec 根据定义,不可变集合是不可变的。据我所知,它们是从头开始创建的,以利用不变性。他们将传达正确的意图。

标签: c#


【解决方案1】:

给定任何IEnumerable&lt;T&gt; foo,使用foo.ToList().AsReadOnly()。这将创建一个包含foo 元素的新List&lt;T&gt;,即使已经是一个列表,然后围绕该列表创建一个只读包装器。由于 ReadOnlyCollection&lt;T&gt; 的基础集合是您刚刚创建的集合,因此没有其他任何东西可以引用它,因此没有其他东西能够更改它(保存反射 tomfoolery)。

【讨论】:

  • 但我需要为此查看代码。我想立即看到它具有不可更改的 uynderlying 集合的只读。所以我需要创建我认为的新类型。
【解决方案2】:

使用 ReadOnlyCollection 集合,您可以确定客户端代码无法修改集合,即从集合中添加或删除元素。但是客户端代码仍然可以修改您的集合中包含的项目:

myReadOnlyCollection.Add(new Object())// error, cannot add/remove items to readonlyCollection
MyObjet obj = myReadOnlyCollection[3] // get the 3rd item in the collection, ok;

obj.someProperty = 9; // ops, the object contained in the ReadOnlyCollection has been changed!

你有两个不同的问题要面对:

  • 确保您的收藏始终包含相同的对象 -> 使用 只读集合
  • 确保集合中的每个对象都不能 修改 -> 集合的类型 T 必须是不可变的

【讨论】:

    【解决方案3】:

    是的。您可以使用

    的实例
    ReadOnlyCollection<T>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-18
      • 1970-01-01
      • 2012-11-25
      • 2020-06-17
      • 1970-01-01
      • 2019-03-15
      • 2011-03-14
      • 2011-09-30
      相关资源
      最近更新 更多