【问题标题】:Why does List<T> implement IReadOnlyList<T> interface? [duplicate]为什么 List<T> 实现 IReadOnlyList<T> 接口? [复制]
【发布时间】:2014-03-08 07:02:46
【问题描述】:

为什么List&lt;T&gt; 实现IReadOnlyList&lt;T&gt; 即使List&lt;T&gt; 不是只读的?

【问题讨论】:

  • 我认为您混淆了派生和实现的基础。类派生自基类,但它们实现接口。牢记这一点解释了这两个概念之间的差异。你不是说IList&lt;T&gt;IReadonLyList&lt;T&gt;,只是说它可以作为一个。
  • @itsme86 使用他们所做的设计实际上是一个非常困难的设计决策。有人可能合理地期望IReadOnlyList永远改变,也就是说它是不可变的,而不是说它是对可变 使用该引用(不进行强制转换)根本无法改变的列表。由于这种混淆,实际上对List 实施IReadOnlyList 的决定存在一些阻力。
  • 好问题。在我看来,这是一个糟糕的界面命名。它应该被称为IAccessableByIndexList 之类的东西,虽然这也不是很好,但它不会欺骗您认为该集合必须是只读的。
  • 这似乎很愚蠢。你可以有一个类Finger 实现了一个接口IWritingUtencil(它只能在沙子、雪地、流血时工作?),但我认为手指不一定是书写工具;只是它可以作为一个。
  • 我一直认为IReadOnlyList 是一个不幸的误称。 IReadableList 将是首选。我想这就是它很少被使用的原因。

标签: c# .net


【解决方案1】:

它允许您公开该列表的只读“代理”,以便您可以将该接口引用传递到其他地方并知道代码不会改变列表。 (从技术上讲,它可以尝试将其转换回 List 之类的东西并对其进行变异,但它不应该那样做。)

它还允许一个方法明确指出当它需要接受一个列表时,它不会改变它。

ListIList 不同,拥有只读接口还允许该接口是协变的。

【讨论】:

  • 不同意第一段。如果您返回一个应该保持只读的集合,您应该将它包装在一个实际强制只读的数据结构中,而不仅仅是声明返回类型“IReadOnly”。它作为 input 参数类型最有用,您需要一些可索引但不一定可变的东西(但您不应该依赖所述输入 可变的假设)。这只是一个名称不佳的接口。
  • @nmclean 第一段解决的问题与第二段完全相同,只是从调用者的角度来看,而不是作者。调用者正在创建他们列表的代理,该代理是只读的,表示他们正在传递给某些东西。
  • 如果调用者正在解决同样的问题(确保外部代码不会改变列表),那么我也不同意第二点。如果调用者想要保留对其集合的控制权,它还应该在传递之前对其进行包装。 IROL 的参数类型不是承诺。它只是意味着它是所需的最小接口。
【解决方案2】:

您可以从子类型的角度来考虑这一点。如果您不修改常规列表,则它可以是只读列表,即List&lt;T&gt;IReadOnlyList&lt;T&gt; 的子类型(我不确定C# 类型是否真的支持这一点)。键入允许您指定特定代码段不会对列表进行任何更改。

这种事情的另一个例子是在 C 中,您可以将int 传递给接受const int 的方法,或者将int 传递给期望volatile int 的方法。比需要的更严格地对待论点并没有害处。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-22
    • 1970-01-01
    • 2011-04-04
    • 2023-03-29
    • 1970-01-01
    • 2012-10-02
    • 1970-01-01
    相关资源
    最近更新 更多