在.NET 4.5中引入IReadOnlyList<T>
时,有一会儿我认为难题的缺失部分终于被插入到位:一种传递真正的只读可索引接口(interface)的方法,以前我必须使用自己的只读接口(interface)并创建包装类围绕一切。
我期望将接口(interface)放置在“自然”层次结构内,理想情况下是:
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>
。是否有一个原因?
一些说明:
注意
IReadOnlyList<T>
仅仅是一个约定,它声明列表提供了一种获取列表计数和读取特定索引值的方法。它的名字不好用,因为它没有强制实际的实现是只读的。List<T>
实现IEnumerable<T>
,IList<T>
继承自IEnumerable<T>
,但这并不意味着只能枚举来表示这些类。因此,如果您希望将列表传递给方法,并且仅允许对其进行索引(读取),但不能对其进行修改,则需要将其包装在新实例中。同时,您可以将其传递给接受
IEnumerable<T>
或IList<T>
的方法,而无需对其进行包装。这是我发现要打破的东西。我也相信专有名称应该像
ICountable
的IReadOnlyCollection
和IIndexable
的IReadOnlyList
一样:IEnumerable<T>
.GetEnumerator()
-> ICountable<T> : IEnumerable<T>
.Count
-> IIndexable<T> : ICountable<T>
.Item[...]
-> IList<T> : IIndexable<T>
.Add(...)
.Clear()
.Contains(...)
(etc)
最佳答案
@ w.b在包含答案的评论中放置指向New interfaces IReadOnlyList and IReadOnlyDictionary的链接:
为了更清楚地解释这一点:
假设为.NET 4.0编写的程序包含一个实现MyList<T>
的IList<T>
类。显然,由于该接口(interface)不存在,因此无法实现IReadOnlyList<T>
。
现在假定系统管理员安装了.NET 4.5,并假定.NET 4.5使IList<T>
实现IReadOnlyList<T>
。
如果随后将要加载程序,则运行时将检测到MyList<T>
声称实现了IList<T>
,但实际上并未实现所有方法:它没有实现IReadOnlyList<T>
的方法。该程序将不再起作用。
C#编译器也许可以按名称匹配方法,但是运行时不这样做。由于.NET 4.5应该具有向后二进制兼容性,因此即使这些其他接口(interface)包含所需方法的严格子集,也无法扩展这些接口(interface)以实现其他接口(interface)。
关于c# - 为什么 `IList<T>`不继承自 `IReadOnlyList<T>`?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35938995/