【问题标题】:How and when does .NET actually compile code?.NET 如何以及何时实际编译代码?
【发布时间】:2009-08-05 22:53:40
【问题描述】:

假设您使用 C#、VB 和 .NET 编写了一个应用程序 当你点击构建时,它真的编译你的代码吗?我是这么认为的,直到我开始在我的一些程序集中使用 redgates 反射器并逐字查看我的代码。我本来希望展开循环和其他过多的优化,而不是什么。

那么编译实际发生在什么时候?我认为当它被构建时,代码变成了 IL(中间语言),当执行发生时,它正在加载到 CLR 中?它是否仅在 CLR 期间进行优化,而不是在构建时进行优化?

【问题讨论】:

  • @Jorge 我不确定这是否完全重复。我认为这个问题涉及到一些相同的问题,但实际上是由“为什么我在 Reflector 中看到我自己的代码?”这个问题所激发的。
  • @Rex 你能链接到这个问题吗?我搜索了该网站并在谷歌上搜索它,但只在这里登陆。谢谢。

标签: .net clr intermediate-language


【解决方案1】:

当你在 VS 中编译时

  1. 您的源代码被编译成称为通用中间语言 (CIL) 或 MSIL(Microsoft 中间语言)的字节码。
  2. 每个类和每个方法(以及所有其他事物 :O)的元数据都包含在生成的可执行文件(无论是 dll 还是 exe)的 PE 标头中。
  3. 如果您要生成可执行文件,PE 标头还包括一个传统的引导程序,该引导程序负责在您执行可执行文件时加载 CLR(公共语言运行时)。

当你执行时:

  1. 引导程序初始化 CLR(主要通过加载 mscorlib 程序集)并指示它执行您的程序集。
  2. CLR 执行您的主条目。
  3. 现在,类有一个向量表,其中保存了方法函数的地址,因此当您调用 MyMethod 时,会搜索该表,然后对该地址进行相应的调用。启动时,所有表的所有条目都有 JIT 编译器的地址。
  4. 当调用此类方法之一时,将调用 JIT 而不是实际方法并获得控制权。然后,JIT 将 CIL 代码编译为适合架构的实际汇编代码。
  5. 编译代码后,JIT 会进入方法向量表,并将地址替换为已编译代码之一,这样每个后续调用都不再调用 JIT。
  6. 最后,JIT 处理编译代码的执行。
  7. 如果您调用另一个尚未编译的方法,则返回 4... 以此类推...

我也在这里发布答案,因为另一个问题并不是关于这个......

【讨论】:

  • When you compile in VS Your source code is compiled into IL,你能解释一下Visual Studio是如何编译成IL的吗? , VS 是否在内部调用 C# 编译器,它在我们的机器上安装了 .NET Framework?
【解决方案2】:

它在编译时被编译为 IL。 Reflector 的神奇之处在于它“理解”IL 并将其转换回 c#(或 VB.NET 或其他任何东西。在 Reflector 的“选项”菜单下查看,您可以查看任何格式的程序集,包括 IL)。

在 Reflector 中,您实际上看不到原始代码。您正在看到将 IL 翻译成 c#。大多数情况下,这与您编写的内容非常相似,但有一些明显的迹象 - 例如,找到一个您实施 auto-property 的地方:

string MyProperty {get;set;}

你会看到实际编译成什么,是这样的:

public string MyProperty
{
    [CompilerGenerated]
    get
    {
        return this.<MyProperty>k__BackingField;
    }
    [CompilerGenerated]
    set
    {
        this.<MyProperty>k__BackingField = value;
    }
}

【讨论】:

    猜你喜欢
    • 2015-02-22
    • 2016-07-11
    • 1970-01-01
    • 2019-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多