简短版
.NET中,接口不形成层级树。当一个类型实现了一个派生接口时,它就实现了所有“父级”接口。这是规范的一部分。
详细版
IList为什么需要同时继承它们?
它不需要。在GitHub上.NET旧版本的实际源代码中,代码如下:
public interface IList<T> : ICollection<T>
.NET Core的源代码类似于此处
public interface IList<T> : ICollection<T>
这个问题没有解释多重继承的假设是从哪里来的。也许文档被误解了?
好的文档总是会列出类实现的所有接口。如果没有这样做,程序员将不得不追踪多个链接,才能找出一个类执行什么操作、它实现了哪些功能或者其特殊行为是什么。
事实上,COM文档在2000年左右就是这种情况,将类和接口文档分开。那时还没有Google和在线文档,所以要找出一个类执行了什么操作非常困难。几乎不可能找到需要实例化的类来获取特定服务。
Intellisense、参数信息和IDEs也会显示所有已实现的接口,因为
编辑后
因此,在代码中继承的接口是由编译器扩展的,因此存在这样的误解:
interface IX{}
interface IY:IX{}
public class C :IY{
public void M() {
}
}
在Sharplab.io中变成了这样:
public class C : IY, IX
{
public void M()
{
}
}
生成的IL显示了相同的内容:
.class public auto ansi beforefieldinit C
extends [System.Private.CoreLib]System.Object
implements IY,
IX
{
这表明仅从IX
继承与从所有继承的接口继承完全相同。
.NET中的接口确实是一个接口,字面上。就像墙上插座是一个接口,4针音频插孔也是一个接口一样。4针音频插孔“继承”1个立体声和1个麦克风连接。立体声连接“继承”2个单声道连接。
我们看不到2个引脚集,我们看到并使用2个单声道和1个麦克风引脚。
这在规范中有说明
在.NET中,接口确实是API规范,而不是实现。当一个类实现继承自其他接口的接口时,它将实现所有这些接口。接口不会像类那样形成层次结构树。
来自 ECMA CIL标准 的 接口类型派生
节(1.8.9.11)
- 对象类型形成单个继承树;接口类型不是这样。
- 对象类型继承指定如何继承实现;必需接口不是这样,因为接口不定义实现。必需接口指定实现对象类型应支持的其他合同。
为了强调最后一个差异,请考虑一个只有一个方法的接口IFoo。从它派生的接口IBar,要求任何支持IBar的对象类型也支持IFoo。它没有说明IBar本身将具有哪些方法。
IList
(或<T>
)列出了一些接口。这是ILSpy的一个副作用。如果一个类实现了IA并且IA暗示IB,ILSpy将会把该类列为同时实现了IA和IB。参考源代码、Github、文档,它们只列出了ICollection。 - Lasse V. Karlsenpublic interface IA { } public interface IB : IA { } public class Test : IB { }
然后对其进行反编译。Test
类将被反编译为public class Test: IB, IA
。这就是为什么我们要求提供源代码的原因。 - Lasse V. Karlsen