【问题标题】:Interface Compilation接口编译
【发布时间】:2016-03-08 08:44:46
【问题描述】:

关于 C# 接口的快速问题。我想知道它们究竟是如何编译和使用汇编的。

我想接口没有编译成程序集。我想接口定义是在编译时编译到类中的,所以接口本质上是一个高级语言概念。

有人可以告诉我我的想法是否正确/不正确吗?当我读到接口没有被实例化时,我得出了这个结论,它们是它们自己的实体。但是另一方面,我也读到它们是引用类型,这让我感到困惑,因为这表明它们是实例化的?

非常感谢。

【问题讨论】:

  • “我想接口没有编译成程序集” 当然可以,否则其他程序集将无法使用它们。甚至internal 接口也在程序集中。它们不会在编译时“烘焙”到一个类中,否则它们可能与其他实现者没有关系。将接口想象成合同,您承诺实现类遵守合同。合同可以传递并用作实际实施的代理。
  • 接口没有实现,因此程序集中不会有任何 MSIL。但它仍然是一种类型,因此它会像任何类型一样出现在元数据中。创建元数据当然是编译器的工作。

标签: c# class inheritance interface compilation


【解决方案1】:

没有接口是不可实例化的(这是一个词吗?),但它们是“真实类型”,您可以拥有接口类型的变量,并且您可以在运行时使用反射访问此类型信息,因此它们确实存在于编译的程序集。

【讨论】:

    【解决方案2】:

    接口必须转换为二进制文件。曾经可能会争辩说它们应该被编译成一个类,但这是不正确的,因为一个接口可以由多个类实现。想象一个案例,当你有一个项目,你实现了 20 种树。当然,如果你有一个 Tree 的接口,每个类都会实现这个接口,那么,如果事情如你所想,那么同一个接口将被编译成 20 个类。现在,想象一下具有许多接口、由许多类实现的大型项目。您会意识到这将意味着浪费大量资源。

    【讨论】:

      【解决方案3】:

      我只是反汇编了一个只包含一个接口的小程序:

      public interface IFoo {
          void Foo();
      }
      

      这就是我从中得到的:

      .class interface public auto ansi abstract IFoo {
          // method line 3
          .method public virtual hidebysig newslot abstract 
             instance default void Foo ()  cil managed 
          {
             // Method begins at RVA 0x0
          } // end of method IFoo::Foo
      } // end of class IFoo
      

      所以,如果你所说的 Assembly 是指 MSIL,答案是肯定的,它们被视为类。

      【讨论】:

      • 谢谢 :) 我明白了。刚刚在.NET Fiddle 上玩了一下,似乎接口被编译成类。继承类和继承接口的区别在于,它们是使用类的'extends'关键字和接口的'implement'关键字来继承的。我现在的理解是它们实际上被编译成类,除了语言限制这些类的实例化。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-11
      • 1970-01-01
      • 2014-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多