如何防止更改 IReadOnlyList<T>?

Posted

技术标签:

【中文标题】如何防止更改 IReadOnlyList<T>?【英文标题】:How to prevent changes to an IReadOnlyList<T>? 【发布时间】:2019-07-09 05:23:40 【问题描述】:

我需要使用IReadOnlyList&lt;T&gt; 作为返回参数,因为它最符合我的需求,但正如您在下面的示例中所见,如果它不是真正只读的,您仍然可以修改它包装的列表。

using System.Collections.Generic;
using System.Collections.Immutable;

public class Test

    public Test()
    
        // return an IReadOnlyList that wraps a List, we can modify content
        var list1 = GetList1();
        if (list1 is List<Section> sections1) // can be true
        
            sections1.Clear();
        

        // return an IReadOnlyList that wraps an ImmutableArray, we cannot modify content
        var list2 = GetList2();
        if (list2 is List<Section> sections2) // never true
        
            sections2.Clear();
        
    

    public static IReadOnlyList<Section> GetList1()
    
        return new List<Section> new Section();
    

    public static IReadOnlyList<Section> GetList2()
    
        return ImmutableArray.Create(new Section());
    


public struct Section


问题:

ImmutableArray&lt;T&gt; 看起来很棒,因为它是真正的只读的,唯一的事情是我不想/不需要公开返回允许生成副本的更改的 fully-featured class。

因此我坚持返回IReadOnlyList&lt;T&gt;,因为它的意图很简单,但我需要解决可能修改的列表问题。

问题:

ImmutableArray&lt;T&gt; 作为IReadOnlyList&lt;T&gt; 返回是正确的方法吗?

如果没有,你能建议怎么做吗?

【问题讨论】:

请记住,IReadOnlyList 不会“包装”任何内容。它仍然是同一个列表对象。 List 实现 IReadOnlyList 这就是您访问它的方式。这就像在手机上盖上一个盖子,隐藏了屏幕的下半部分——它仍然是同一部手机。我想说ImmutableArray 是解决此问题的正确方法,如果您想做的不仅仅是阻止人们意外修改列表。 好吧,用这个词不合适! 抱歉,我要编辑我的问题,因为我忘了提一些事情。 如果您不公开原始列表,您可以使用 AsReadOnly 方法,请参阅docs.microsoft.com/en-us/dotnet/api/…,它创建了一个只有只读集合方法的包装器。 @ckuri 看看docs.microsoft.com/en-us/dotnet/api/…中的备注部分 【参考方案1】:

IReadOnlyList 不是这样工作的

IReadOnlyList Interface

IReadOnlyList&lt;T&gt; 代表一个列表,其中的编号和顺序 的列表元素是只读的。 列表元素的内容不是 保证是只读的

如果您想要Immutable Collection,请查看

System.Collections.Immutable Namespace

System.Collections.Immutable 命名空间包含接口和 定义不可变集合的类。

【讨论】:

以上是关于如何防止更改 IReadOnlyList<T>?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 List<T> 在 .NET 4.5 中实现 IReadOnlyList<T>?

IList<T> 和 IReadOnlyList<T>

有没有办法将 IReadOnlyCollection<T>/IReadOnlyList<T> 与 protobuf-net 一起使用

js如何防止负数的产生?

Rayon 如何防止线程之间使用 RefCell<T>、Cell<T> 和 Rc<T>?

如何删除excel中数字上的隐藏引号,以防止更改格式