简体   繁体   English

C#IReadOnlyList <t> 防护立即被垂头丧气所破坏,还是我错过了一些东西?

[英]C# IReadOnlyList<t> protection instantlly subverted by downcast, or am I missing something?

Given the below: Is it truly the case that if an IReadOnly(of T) was conceived from an extant MutableEquivalent(of T), that simply casting to the mutable version allows full access, and changes to an object others may rely on to have static elements/count? 给出以下内容:如果确实是从现存的MutableEquivalent(of T)构想了一个IReadOnly(T),那么将其简单地转换为可变版本就可以实现完全访问,而对他人可能依赖的对象进行更改的情况是否确实如此?静态元素/数量? The output below shows my "THIRD INJECTION" string, despite iterating through a read only collection. 尽管遍历一个只读集合,但下面的输出显示了我的“ THIRD INJECTION”字符串。 Is it just manners and self control that prohibit casting a readonly collection down? 仅仅是举止禁止自制只读集合的​​方式和自我控制吗? Are you supposed to see the interface provided, and bear its restrictions, cast-invariant, due to type alone? 您是否应该仅由于类型而看到提供的接口并承受其强制转换不变的限制? Thanks for any clarification on what this interface and others like it truly promise/guarantee. 感谢您对该接口和其他类似接口的真正承诺/保证进行澄清。

EDIT- This is not a duplicate of IReadOnlyCollection <T> vs List.AsReadOnly() since I didn't mention List.AsReadOnly() in my question, nor IReadOnlyCollection. 编辑-这不是IReadOnlyCollection <T>与List.AsReadOnly()的重复,因为我在问题中也没有提及List.AsReadOnly(),也没有提到IReadOnlyCollection。 Those were introduced by responders. 这些是由响应者介绍的。 This was a question on underlying mutable list exposure when behind an IReadOnly interface. 这是一个在IReadOnly接口后面时有关底层可变列表公开的问题。 There are some overlaps in some comments, but a question such as "What does IReadOnly actually do for its underlying mutable List(of T)?" 某些注释中有一些重叠之处,但有一个问题,例如“ IReadOnly实际上对其底层可变T(List)做了什么?”。 duplicates the spirit of my question. 复制了我的问题的精神。 Not "What is the difference between these two entities pertaining to read only?", since I only mentioned one. 因为我只提到了一个,所以不是“这两个属于只读的实体有什么区别?”。

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"};

}

From your comment : 根据您的评论

I didn't realize the interface was more a loose protection for a programmer rather than a 'const'-esque' barrier to mutation. 我没有意识到接口对程序员来说不是一个宽松的保护,而不是突变的“ const”式障碍。 … I assumed, incorrectly, that a downcast from a readonly to mutable would be an invalid cast. …我错误地认为从只读到可变的转换将是无效的转换。

An interface isn't intended as "protection" of any sort, at all. 接口根本不打算作为任何形式的“保护”。 It is simply a promise to implement specific features. 这只是实现特定功能的承诺。

The benefit of IReadOnlyList<T> is one of semantics and now, with generic type variance in C#, flexibility. IReadOnlyList<T>的好处是语义之一,现在,由于C#具有通用类型差异,因此具有灵活性。 The semantic benefit allows you to expose a list in a way that expresses the intent to only read it and not modify it. 语义上的好处使您可以以表示只读取而不修改的意图的方式公开列表。

The flexibility comes in, because the type parameter can be made covariant. 由于类型参数可以协变,因此具有灵活性。 This allows implicit conversions from IReadOnlyList<T1> to IReadOnlyList<T2> where T1 inherits T2 . 这允许从IReadOnlyList<T1>IReadOnlyList<T2>隐式转换,其中T1继承T2

It is up to the implementor of the interface to decide whether true immutability is provided or not. 由接口的实现者决定是否提供真正的不变性。 If you want a collection to be truly immutable, you would use ReadOnlyCollection<T> as the implementation for IReadOnlyList<T> , instead of List<T> . 如果希望集合是真正不变的,则可以使用ReadOnlyCollection<T>作为IReadOnlyList<T>的实现,而不是List<T> You can pass any IList<T> implementation to the ReadOnlyCollection<T> constructor, and the new object will expose that IList<T> object's data without allowing modification (directly…you can always, of course, cheat with reflection, even with a object that is truly immutable and not just a wrapper like ReadOnlyCollection<T> ). 您可以将任何IList<T>实现传递给ReadOnlyCollection<T>构造函数,新对象将公开IList<T>对象的数据而无需进行修改(直接……当然,您始终可以通过反射来欺骗,即使使用真正不可变的对象,而不仅仅是像ReadOnlyCollection<T>这样的包装器。

With any interface, you are always only dealing with a specific object, which has a specific type, that type always implements some functionality, and can always be cast to the original type, as well as any other interfaces it might implement. 对于任何接口,您始终只处理具有特定类型的特定对象,该类型始终实现某些功能,并且始终可以转换为原始类型以及它可能实现的任何其他接口。

It would be a mistake to think of interfaces as in any significant way a form of protection . 将接口以任何重要方式视为一种保护形式是错误的。 They aren't. 他们不是。 They just express what an object is able to do . 他们只是表达一个物体能够什么。

The underlying collection of READONLY is a mutable list, this is the reason that the cast actually succeeds when creating the hack variable. READONLY的基础集合是一个可变列表,这就是在创建hack变量时hack成功的原因。 READONLY is read-only for any of its consumers, but the underlying list can still be mutated. READONLY对其任何使用者都是只读的,但是基础列表仍然可以被突变。

UPDATED : As Sir Rufo pointed out, exposing the list by way of list.AsReadOnly() will prevent hard casting. 更新 :正如Rufo爵士指出的那样,通过list.AsReadOnly()公开列表将防止强制转换。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 c#日期组件错误或我错过了什么? - c# Date component bug or am i missing something? 需要了解C#片段,我是否缺少明显的东西? - Need to understand C# piece, am I missing something obvious? 使用IList进行C#重载解析 <T> 和IReadOnlyList <T> - C# overload resolution with IList<T> and IReadOnlyList<T> C# 扩展适用于控制台应用程序,但不适用于 MVC Web 应用程序。 我错过了什么吗? - C# Extensions working in console application but not in MVC web application. Am I missing something? 有没有一种特殊的方法可以在 c# 的类中使用 Random.Next 或者我只是缺少一些基本的东西? - Is there a special way to use Random.Next inside a class in c# or am i just missing something basic? 用于 c# REST API 中的本机/桌面应用程序的 Keycloack,无法正常工作还是我遗漏了什么? - Keycloack for native /desktop application in c# REST APIs, not working properly or am I missing something? 表现怪异的transform.lookat或我错过了一些东西(unity3d C#) - transform.lookat behaving weirdly OR I am missing something (unity3d c#) 针对C#异步的秒表:我被秒表所迷惑了,还是有我不知道的东西? - Stopwatch against C# Async: Am I fooled by the stopwatch or there's something there I don't know? C#,MySQL-命令执行期间遇到致命错误-检查了其他解决方案,这是我所缺少的 - C#, MySQL - fatal error encountered during command execution- Checked other solutions, something I am Missing 为什么不知道文件夹在winrt中起作用? 我想念什么吗? - Why isn't knownfolders works in winrt? Am I missing something?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM