关于这一点有很多相互矛盾的信息。虽然有人说 C# 是编译的(因为它被编译成 IL,然后在运行时编译成本机代码),但其他人说它被解释为它需要 .NET。EN 维基 说:
许多解释语言首先被编译成某种形式的虚拟机代码,然后在运行时被解释或编译为本机代码。
所以我很困惑。谁能解释清楚?
关于这一点有很多相互矛盾的信息。虽然有人说 C# 是编译的(因为它被编译成 IL,然后在运行时编译成本机代码),但其他人说它被解释为它需要 .NET。EN 维基 说:
许多解释语言首先被编译成某种形式的虚拟机代码,然后在运行时被解释或编译为本机代码。
所以我很困惑。谁能解释清楚?
C# 由 c# 编译器编译成 IL。
然后根据需要将此 IL 即时编译 (JIT) 成主机的本机汇编语言。不过,可以编写一个解释 IL 的 .NET 运行时。即使这样做了,我仍然认为 c# 是一种编译语言。
纯编译语言有一些优点。速度,通常,通常是工作集大小。纯解释型语言有一些优点。不需要显式编译阶段的灵活性,允许我们就地编辑,并且通常更容易移植。
在这种情况下,jitted 语言适合中间立场。
这就是为什么我们可能将 jitted 语言视为编译或解释的原因,这取决于我们关心达到哪个指标的哪个位置,以及我们对一个或另一个的偏见。
C# 也可以在第一次运行时编译,就像在 ASP.NET 中发生的那样,这使得它在这种情况下接近解释(尽管在这种情况下它仍然被编译为 IL 然后被 jitted)。当然,在这种情况下,它几乎具有解释的所有优点(与经典 ASP 中使用的 VBScript 或 JScript 相比),以及编译的许多优点。
严格来说,没有一种语言是 jitted、interpreted 或compiled qua 语言。我们可以将 NGen C# 转换为本机代码(尽管如果它执行诸如动态加载程序集之类的操作,它仍将使用 IL 和 jitting)。我们可以为 C 或 C++ 编写一个解释器(有几个人已经这样做了)。不过,在其最常见的用例中,C# 被编译为 IL,然后进行 jitted,这既不是解释的经典定义,也不是编译的经典定义。
基于意见的语义和陈述太多。
首先:C# 不是解释型语言;CLR 和 JVM 被认为是“运行时”或“中间件”,但同样的名称也适用于 Perl 之类的东西。这在关心名字的人中造成了很多混乱。
引用运行时的术语“解释器”通常意味着现有代码解释一些非本地代码。有两大范式:解析读取原始源代码并采取逻辑动作;字节码执行首先将代码编译为非本地二进制表示,这需要更少的 CPU 周期来解释。
Java 最初编译成字节码,然后经过解释器;现在,JVM 读取字节码并及时将其编译为本机代码。CIL 也是如此:CLR 使用即时编译来编译本机代码。
考虑运行源代码、运行字节码、编译为本机、即时编译、通过编译器运行源代码到即时本机等的所有组合。一种语言是编译还是解释的语义变得毫无意义。
例如:许多解释语言使用即时字节码编译。C#编译成CIL,JIT编译成native;相比之下,Perl 立即将脚本编译为字节码,然后通过解释器运行此字节码。您只能以 CIL 字节码格式运行 C# 程序集;您只能以原始源代码格式运行 Perl 脚本。
即时编译器还运行许多外部和内部工具。运行时跟踪各种函数的执行,然后调整代码布局以优化其特定执行流程的分支和代码组织。这意味着 JIT 代码可以比本机编译代码运行得更快(就像 C++ 通常是,或者像 C# 通过 IL2CPP 运行),因为 JIT 在运行时会根据代码的实际执行情况调整其优化策略。
欢迎来到计算机编程的世界。我们决定让它变得非常复杂,然后给所有东西附加非描述性的名字。目的是在没有实际意义的单词的定义上引发激烈的争论。
如果您觉得、了解或老派,编译的 EXE 正在从源代码转换为机器代码,那么 C# 将被解释。如果您认为已编译意味着将源代码转换为其他代码(例如字节码),那么是的,它已转换。对我来说,任何需要运行时处理才能在为其构建的操作系统中工作的东西都会被解释。
看这里:http: //msdn.microsoft.com/library/z1zx9t92
用 C# 编写的源代码被编译成符合 CLI 规范的中间语言 (IL)。
(...)
执行 C# 程序时,程序集被加载到 CLR 中,CLR 可能会根据清单中的信息执行各种操作。然后,如果满足安全要求,CLR 将执行即时 (JIT) 编译,将 IL 代码转换为本地机器指令。
首先让我们了解解释和编译的定义。
“编译”(当指代代码时)意味着将代码从一种语言翻译成另一种语言。通常从人类可读的源代码到目标处理器可以...处理的机器代码。
“解释”(当提到代码时)也意味着将代码从一种语言翻译成另一种语言。但这一次,它通常用于从人类可读的源代码转换为中间代码,由虚拟机获取,虚拟机将其解释为机器代码。
只是要清楚
源代码 -> 编译器 -> 机器代码
源代码 -> 编译器 -> 字节码 -> 解释器 -> 机器代码
理论上,任何语言都可以被解释或编译。通常,Java 被编译成字节码,Java 虚拟机将其解释为机器码。C# 通常被解释为由 CLR、公共语言运行时、另一个虚拟机编译的字节码。
到目前为止,整个事情都是营销噱头。添加了术语“解释”(或至少增加了使用量)以帮助展示即时编译的简洁性。但他们本可以只使用“编译”。区别更多的是对英语语言和商业趋势的研究,而不是技术性质的任何东西。
C# 在其生命周期中同时被解释和编译。C# 被编译为由 VM 解释的虚拟语言。
混淆源于“编译语言”的模糊概念。
从某种意义上说,“编译语言”是用词不当,因为编译或解释不是语言的属性,而是运行时的属性。
例如,您可以编写一个 C 解释器,但人们通常称其为“编译语言”,因为 C 实现编译为机器代码,并且该语言的设计考虑了编译。
大多数语言(如果不是全部)都需要一个解释器,将它们的脚本翻译成机器代码,以便让 cpu 理解并执行它!
每种语言处理翻译过程的方式都不同!
例如,“AutoIt”就是我们可以描述为 100% 解释性的语言!
为什么?
因为“AutoIt”解释器在其脚本执行时不断需要!请参见下面的示例:
Loop, 1000
Any-Code
“AutoIt”解释器必须将“Any-Code”翻译成机器代码 1000 次,这会自动使“AutoIt”成为一种慢速语言!
另一方面,C# 处理翻译过程的方式不同,C# 的解释器只需要一次,在脚本执行之前,之后在脚本执行期间不再需要!
C# 的解释器只需将“Any-Code”一次翻译成机器代码,这会自动使“C#”成为一种快速语言!
所以基本上,
在脚本执行期间需要其解释器的语言是“解释语言”!
只需要一次解释器(在脚本执行之前)的语言是“编译语言”!
最后,
“AutoIt”是一种“解释语言”!
“C#”是一种“编译语言”!
我相信这是一个相当古老的话题。
从我的角度来看,解释代码将通过解释器,逐行翻译并同时执行。与示例 javascript 一样,它是一个解释代码,当一行 javascript 遇到错误时,脚本就会中断。
在编译代码时,它会通过编译器,一次将所有代码转换为另一种形式的代码,而不是先执行它。执行是在另一个上下文中。
C# 与 Java 一样,具有混合语言处理器。混合处理器执行解释和编译的工作。
由于计算机只能执行二进制代码,因此任何语言都会导致在某一时刻产生二进制代码。问题是:该语言是否允许您以二进制代码生成程序?如果是,那么它是一种编译语言:根据定义,“编译语言”中的“编译”是指编译成二进制代码,而不是转换成一些中间代码。如果该语言导致为程序生成此类中间代码,则需要额外的软件来从该代码执行二进制编译:它是一种解释性语言。由C#“编译”的程序是否可以在一台机器上直接执行,而这台机器上根本没有安装任何其他软件?如果不是,那么它是一种解释语言。对于解释型语言,它是一个解释器,将生成底层二进制代码,大部分时间以动态方式生成,因为这种机制是此类语言灵活性的基础。雷姆。:有时它看起来并不明显,因为解释器被捆绑到操作系统中
如果我们同意解释器的定义 «在计算机科学中,解释器是直接执行(即执行)用编程或脚本语言编写的指令的计算机程序,而无需事先将它们编译成机器语言程序。» 毫无疑问:C# 不是解释型语言。