Lou*_*Lou 28 .net c# generics .net-4.5
什么时候IReadOnlyList<T>在.NET 4.5中引入,有一段时间我认为拼图的缺失部分最终被插入到位:一种传递真正的只读索引接口的方法,以前我必须使用我自己的只读接口并创建包装器围绕一切的课程.
我期待接口被放置在"自然"层次结构中,理想情况是:
IEnumerable<T>
.GetEnumerator()
-> IReadOnlyCollection<T> : IEnumerable<T>
.Count
-> IReadOnlyList<T> : IReadOnlyCollection<T>
.Item[...]
-> IList<T> : IReadOnlyList<T>
.Add(...)
.Clear()
.Contains(...)
(etc)
Run Code Online (Sandbox Code Playgroud)
但是,事实证明,IList<T>不会继承IReadOnlyList<T>.
是否有一个原因?
小智 32
@wb 在包含答案的注释中放置了新接口IReadOnlyList和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>,但实际上并没有实现所有方法:它没有实现IReadOnlyList<T>的方法.该计划将不再有效.
C#编译器可能能够按名称匹配方法,但运行时不会这样做.由于.NET 4.5应该具有向后二进制兼容性,因此无法扩展接口以实现其他接口,即使这些其他接口包含所需方法的严格子集也是如此.