这听起来像是个很是高大上的名字,上学的时候咱们学过的编译原理或者编译技术其实是在讲如何将高级程序语言如C++编译为计算机能够理解的汇编语言,这里说的编译原理只是想说明在.NET的世界里编译这件事儿和传统的C++有什么区别和联系。先来简单的说一下传统的作法,在C++里,但你编译一个应用程序好比一个EXE文件或者是DLL(注意这里的DLL叫作动态连接库,只是到了.NET中才才被叫作程序集)时,实际上编译器作的事情就是直接将你写的C++代码编译为汇编语言,而后以二进制的形式存放在EXE或者DLL文件中,当被执行的时候,CPU就能够直接读到汇编代码开始运行了。固然提及来简单,里面仍是有很是多的细节问题,咱们须要关注的重点是,C++编译器作到的事情是将高级语言直接编译为汇编语言。html
接下来,咱们来看一看在.NET中咱们如何处理。在说明以前,咱们来回顾一下一个很是经典的说法,你看任何一本介绍.NET的书都会在开篇宣称.NET是跨平台跨语言的高级运行时,可是.NET是如何作到的呢?咱们引入一个很是关键的概念叫作Intermediate Language简称IL,中文叫作中间语言。linux
当你写了一段程序(假设是一个Console Application EXE的项目),在Visual Studio中点击F5编译并运行这个按钮的时候,实际上都发生了些什么呢?程序员
注意,.NET的程序要运行,其实是须要两次编译的,一次是在开发的时候,另一次则是在运行的时候。那么这样作实际上解决了.NET跨语言跨平台这个问题。.面试
NET上会不少种语言,好比C#,VB.NET, C++.NET, F#,这些语言开发出来的程序,只要机器上装了.NET Framework就均可以运行,这是由于不一样的语言在第一次(开发过程)编译的时候都会被编译为IL,也就是说,一样的一个功能,用C#写出来和F#写出来编译出来的IL是同样的(固然编译器可能根据不一样的高级语言特色有所优化,可是基本一致)。这样作的好处是什么呢?很简单,好比你用C#写了一个feature,我用F#加载你的DLL就可使用你的程序集了。这看起来没什么,可是你能想一想一下若是C++能够很是简单的调用Java的类库,这个世界是否是就该疯狂了?再来是跨平台,当你的.NET程序运行的时候,.NET运行时负责将IL编译为汇编语言,在运行编译时,.NET能够根据当前运行的操做系统以及CPU构架的不一样生成彻底不同的汇编语言。可是C++就作不到,你用一种编译器编译出来的东西只能运行在某个特定的平台上,好比VC编译器编译出来的只能跑在windows上,在linux上就完蛋了。这是.NET很是重要的一个框架技术核心,虽然如今被应用的并不普遍,由于除了C#和Windows平台意外,.NET是不多被使用的。可是若是将来微软将.NET技术推广到更多领域,这种跨平台跨语言的框架核心就能显示出价值了。看一下下面这个图。windows
首先,二次编译带来的性能损失。这很容易理解,与C++相比,运行.NET程序在运行的时候多了一次编译,这确定是要慢的。.NET runtime作了一些性能的优化,即由IL编译过的汇编语言会被缓存起来,当第二次再遇到一样的IL的时候,会直接从内存中加载,而再也不被编译。这也就是.NET程序会被指责第一次运行极慢无比的一个重要缘由。好比咱们来看看下面这段code...框架
Console.WriteLine("Hello world"); // first time, compile this function性能
Console.WriteLine("Hello world again"); // second time, load from cache优化
固然为了提升性能,.NET编译器容许将高级语言如C#直接编译为汇编语言,可是并不推荐这样作,这样的会,全部跨平台,跨语言的特性就将消失,这种作法适用于对性能要求极高的应用程序。this
第二,反编译的故事。全部.NET的DLL都是中间语言组成的,因此,你能够用反编译器加载DLL,由中间语言反编译为C#以此看到其余程序集的源代码。固然.NET提供了加密保护机制,当你编译为DLL的时候能够加入扰码,使反编译器没法理解IL。
第三,这是反射的基础。你确定知道反射的故事,在运行时能够动态的加载某个类型中全部的property, field等等,.NET就是经过分析中间语言作到这一点的。在运行时,.NET runtime会加载IL并理解全部的类型定义。
好了,这就是全部.NET编译的基本故事了,虽说和你写code没什么太大关系吧,做为.NET的核心技术框架,这个仍是要了解一下的。That's much for today.