C# IReadOnlyList<t> 保护立即被向下破坏,或者我错过了什么?

sch*_*ter 3 c# collections readonly readonly-collection c#-4.0

鉴于以下情况:如果 IReadOnly(T) 是从现有的 MutableEquivalent(T) 构想出来的,那么简单地转换为可变版本就允许完全访问,并且对其他人可能依赖的对象进行更改,这真的是这样吗?静态元素/数量?下面的输出显示了我的“THIRD INJECTION”字符串,尽管迭代了只读集合。难道只是出于礼貌和自我控制而禁止向下转换只读集合吗?您是否应该看到提供的接口,并承受其限制,强制转换不变,仅由于类型?感谢您对该界面和其他类似界面真正承诺/保证的任何澄清。

编辑-这不是 IReadOnlyCollection<T>与 List.AsReadOnly() 的重复,因为我在问题中没有提到 List.AsReadOnly() ,也没有提到 IReadOnlyCollection 。这些是由响应者介绍的。这是一个关于 IReadOnly 接口后面的底层可变列表暴露的问题。一些评论中有一些重叠,但有一个问题,例如“IReadOnly 实际上对其底层可变列表(T)做了什么?” 重复了我的问题的精神。不是“这两个有关只读的实体之间有什么区别?”,因为我只提到了一个。

static class Program
{

    public static void Main()
    {
        List<string> hack = (List<string>) READONLY;
        hack.Add("THIRD INJECTION");

        foreach (var s in READONLY)
        {
            Console.WriteLine(s);
        }
    }

    public static readonly IReadOnlyList<string> READONLY = new List<string>{"@0", "@1"};

}
Run Code Online (Sandbox Code Playgroud)

Pet*_*iho 5

你的评论中:

我没有意识到该接口对于程序员来说更像是一种松散的保护,而不是“const”式的突变障碍。…我错误地认为从只读到可变的向下转换将是无效的转换。

接口根本不旨在作为任何类型的“保护”。它只是实现特定功能的承诺。

其优点IReadOnlyList<T>之一是语义,而现在,由于 C# 中的泛型类型差异,灵活性。语义的好处允许您以表达仅读取而不修改它的意图的方式公开列表。

灵活性就出现了,因为类型参数可以是协变的。IReadOnlyList<T1>这允许从到IReadOnlyList<T2>的隐式转换T1继承T2

由接口的实现者决定是否提供真正的不变性。如果您希望集合真正不可变,您可以使用, 而不是 的ReadOnlyCollection<T>实现。您可以将任何实现传递给构造函数,新对象将公开该对象的数据而不允许修改(直接......当然,您总是可以通过反射进行欺骗,即使对象是真正不可变的而不仅仅是像包装器这样的对象) 。IReadOnlyList<T>List<T>IList<T>ReadOnlyCollection<T>IList<T>ReadOnlyCollection<T>

对于任何接口,您始终只处理具有特定类型的特定对象,该类型始终实现某些功能,并且始终可以转换为原始类型以及它可能实现的任何其他接口。

如果认为接口在任何重要方面都是一种保护形式,那就大错特错了。他们不是。它们只是表达一个对象能够什么。