为什么接口在IL级别作为"抽象接口"发出?

use*_*993 5 .net c# clr cil roslyn

我一直在努力学习更多有关CLR的知识,同时注意到C#中的以下接口将被编译为包含某种"抽象接口"的IL.

鉴于在C#中将接口声明为抽象是无效的,在IL级别允许抽象接口意味着什么?最初,我想知道这是否是运行时内部表示接口的方式,通过声明一个抽象从而防止它被新增.

它似乎确实遵循了这个想法,如图所示.class.但是,接下来是interface.因此,当运行时似乎支持接口的概念时,需要实际创建抽象的想法似乎没有实际意义.

这引出了几个问题:

  1. 抽象接口的目的是什么,为什么抽象接口在IL级别有效?
  2. 为什么.class interface必要的,这是为什么有效的IL水平?
  3. 如果运行时支持接口的概念,为什么.class还是abstract需要?

C#:

public interface IExample
{
    void SomeMethod(int number);
}
Run Code Online (Sandbox Code Playgroud)

IL:

.class interface public auto ansi abstract IExample
{
    // Methods
    .method public hidebysig newslot abstract virtual 
        instance void SomeMethod (
            int32 number
        ) cil managed 
    {
    } // end of method IExample::SomeMethod

}
Run Code Online (Sandbox Code Playgroud)

Dam*_*ver 11

如果查看如何在IL级别定义元数据(PDF),则所有类型都由.class标头引入(偶数值类型).

interface 被描述为"类型语义属性"(10.1.3)并且用于区分正在定义的内容实际上是接口,而不是所有成员都是抽象的抽象类.

abstract 被描述为"继承属性"(10.1.4),具体表示该类型无法实例化.

这涵盖了预期的含义.至于为什么它们是必要的(即为什么interface不自动暗示 abstract),我相信这样做是为了在这个层面上明确一切.由于您不必经常自己编写IL,因此在某些标记之间存在一些重叠并不是有害的.