为什么`IList <t>`继承自`IReadOnlyList <t>`?

时间:2016-03-11 11:23:25

标签: c# .net generics .net-4.5

当在.NET 4.5中引入IReadOnlyList<T>时,我认为拼图的缺失部分最终被插入到位:一种传递真正的只读索引接口的方法,以前我必须使用我的拥有只读接口并围绕所有内容创建包装类。

我期待将界面放在&#34; natural&#34;层次结构,理想情况下是:

IEnumerable<T> 
.GetEnumerator()
      -> IReadOnlyCollection<T> : IEnumerable<T>
      .Count
            -> IReadOnlyList<T> : IReadOnlyCollection<T>
            .Item[...]
                     -> IList<T> : IReadOnlyList<T>
                     .Add(...)
                     .Clear()
                     .Contains(...)
                     (etc)

但事实证明, IList<T>并未从IReadOnlyList<T> 继承。

这是否有原因?

1 个答案:

答案 0 :(得分:29)

@ w.b在包含答案的评论中添加了New interfaces IReadOnlyList and IReadOnlyDictionary的链接:

  

为什么我们不更改现有接口以扩展只读接口?

     

看起来合理的假设它是有效的,因为只读接口纯粹是读写接口的一个子集。不幸的是,它是不兼容的,因为在元数据级别,每个接口上的每个方法都有自己的插槽(这使得显式接口实现起作用)。

           

Immo Landwerth | .NET Framework团队(BCL)| http://blogs.msdn.com/b/bclteam/

更清楚地解释一下:

假设为.NET 4.0编写的程序包含实现MyList<T>的类IList<T>。它显然无法实现IReadOnlyList<T>,因为该接口不存在。

现在假设系统管理员安装了.NET 4.5,并假设.NET 4.5使IList<T>实现了IReadOnlyList<T>

如果然后加载该程序,运行时将检测到MyList<T>声明实现IList<T>,但实际上没有实现所有方法:它没有实现{ {1}}的方法。该计划将不再有效。

C#编译器可能能够按名称匹配方法,但运行时不会这样做。由于.NET 4.5应该具有向后二进制兼容性,因此接口无法扩展以实现其他接口,即使这些其他接口包含所需方法的严格子集也不会。