【问题标题】:Why does an interface get emitted at the IL level as an "abstract interface"?为什么接口在 IL 级别作为“抽象接口”发出?
【发布时间】:2017-06-08 10:12:20
【问题描述】:

我一直在尝试了解有关 CLR 的更多信息,同时注意到 C# 中的以下接口将被编译为包含某种“抽象接口”的 IL。

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

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

这让我想到了几个问题:

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

C#:

public interface IExample
{
    void SomeMethod(int number);
}

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

}

【问题讨论】:

  • 从语言语法到元数据属性的映射并不总是显而易见的。一般来说,CLR 允许更多,语言设计者选择他想要使用的内容。在这种特定情况下,C# 编译器仅遵循 Ecma-335 第 II.22.37 节中规定的元数据规则:“23. 接口应具有 Flags.Abstract = 1”。将该规范放在手边,您在浏览 MSIL 时会用到它。
  • 这是一个有趣的摘录,谢谢,现在正在阅读。但它并没有给出做出该决定的原因
  • 这是规则的好处,你不必担心如果你不遵守规则可能意味着什么;)

标签: c# .net clr roslyn cil


【解决方案1】:

如果您查看metadata (PDF) 是如何在 IL 级别定义的,所有类型都是由 .class 标头(偶数值类型)引入的。

interface 被描述为“类型语义属性”(10.1.3),用于区分所定义的内容是否确实是接口,而不是所有成员都是抽象的抽象类。

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

这涵盖了预期的含义。至于为什么它们是必要的(即为什么interface 不会自动暗示abstract),我相信这样做是为了让一切显式 在这个级别。由于您不必经常自己编写 IL,因此其中一些标志之间有一些重叠并无害。

【讨论】:

  • 很好的答案,谢谢!我同意,一个接口可能并不特别暗示abstract,所以它可以是明确的。链接也为+1。它被称为 Partition II,这是 ECMA 规范的摘录还是其他一系列文档?
  • @user9993 - 这是page full of the standards。之前链接到的文档是“Microsoft 实施特定版本”集的一部分。
  • @hoodaticus - 让一切明确提供额外的好处 - 它让事情更容易扩展。他们设法引入泛型(没有 Java 的类型擦除)这一事实表明,明确说明否则可以“假定”是一个好方法。
  • @Damien_The_Unbeliever - 好吧!每次我不得不使用 Java 泛型时——每天都这样,我的灵魂充满了仇恨。
猜你喜欢
  • 1970-01-01
  • 2011-01-23
  • 1970-01-01
  • 2010-10-12
  • 2018-07-19
  • 2010-12-27
  • 1970-01-01
  • 2011-01-09
  • 2014-08-27
相关资源
最近更新 更多