关于.net:C#编译器版本和语言版本之间的区别

Difference between C# compiler version and language version

有段时间我认为框架版本和C版本是相同的,所以一旦您在计算机上安装下一个框架版本,就应该使用它。

然后我发现框架并没有直接与C版本链接,在同一台机器上,多个C编译器可以共存,因此编译器和C版本可能应该是相同的。

现在我明白了编译器版本和C版本是不同的…

Visual Studio命令提示(2010):C:\>csc

Microsoft(R)Visual C编译器4.0.30319.33440版对于Microsoft(R).NET Framework 4.5

vs 2013的开发者命令提示:C:\>csc

Microsoft(R)Visual C编译器版本12.0.30110.0C 5

enter image description here

我们可以看到-Vs2010使用编译器版本4.0作为C 4(??我可以这样想,因为没有明确提到);-vs 2013使用C_5的编译器版本12.0(这是明确提到的)

知道使用不同语言版本编译会给用户带来不同的结果

问题

  • 如何找出C版本(不是编译器版本,而是语言版本)使用vs来构建我的具体项目?

  • C编译器和语言版本之间是否存在严格、清晰和透明的链接?

  • 我可以向Visual Studio指示(在从一个Studio版本迁移到另一个Studio版本时)为具体的解决方案使用不同的编译器版本吗?


由于没有人给出足够好的答案,我现在就试试。

首先,C现在已经由微软发布了它的版本历史(显然来自MVP的帖子)。

https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-version-history

因此,您可以很容易地看到为每个新版本添加了哪些新功能。

其次,我们将讨论最初是.NET框架一部分的编译器版本。

下面我列出了一些里程碑(可能不是100%正确,有些版本可能被跳过)。

  • csc.exe1.0(?)对于.NET Framework 1.0(实现C 1.0)。
  • 用于.NET Framework 2.0的csc.exe2.0(Microsoft(R)Visual C_2005编译器版本8.00.50727.8745)(实现C_2.0,以及1.0以实现兼容性)。
  • 用于.NET Framework 3.5的csc.exe3.5(Microsoft(R)Visual C_2008编译器版本3.5.30729.8763)(实现C_3.0和旧版本)。
  • csc.exe4.0(?)对于.NET Framework 4.0(实现C 4.0及更旧版本)。
  • 用于.NET Framework 4.5及更高版本(实现C 5.0及更低版本)的csc.exe4.x(如Microsoft(R)Visual C编译器4.7.2053.0版)。请注意,根据计算机上的.NET框架(4.5.0到4.7.1),版本号变化很大(从4.x到12.x)。

然后,微软使旧的csc.exe过时(因为它们是本机可执行的),转而提供了基于Roslyn的编译器(尽管仍然是csc.exe)。同时,C编译器不再是.NET框架的一部分,而是VS的一部分。

0

  • Roslyn csc.exe1.x(?)实现C 6.0及更旧版本。与VS2015一起装运。
  • Roslyn csc.exe2.x(如Microsoft(R)Visual C编译器版本2.4.0.62122(AB56A4A6))实现C 7.x及更高版本。与VS2017一起装运。

好的,有足够的背景。回到你的问题上来。

问题1:如何找出C版本(不是编译器版本,而是语言版本)使用vs来构建我的具体项目?

答:您可以很容易地从项目设置中看到所使用的语言版本。

Advanced settings

如果不选择显式版本,它可以自动使用编译项目的csc.exe支持的最新版本。

注意@servy在@danilocataldo关于langversion开关的回答下评论了更多细节。这种开关有其设计目标和局限性。因此,例如,即使您强制Roslyn2.x编译器基于C 4.0编译您的项目,编译后的结果将与C 4.0编译器所做的不同。

问题2:C编译器和语言版本之间是否存在严格、清晰和透明的链接?

答:请参考我上面描述的背景,我认为已经回答了这部分。有一个严格、清晰和透明的链接。

问题3:我能否向Visual Studio表明(在从一个Studio版本迁移到另一个Studio版本时)要为具体的解决方案使用不同的编译器版本?

答:与问题1重复。


只是为了补充上一个答案。您应该知道,虽然C语言和C编译器与.NET框架是分开的,但它们仍然依赖于它。

例如,C 5具有await/async语言功能,但您不能将其与.NET 4一起使用,至少不能没有一些额外的操作和nuget包。

另一方面,您仍然可以在.NET 4.0中使用C 6的名称或空传播特性,因为它们完全由编译器实现。


在过去,Visual Studio 2005仅修复为一个.NET版本,C编译器随此版本一起提供。如果您想使用较新版本的vs,还必须切换Visual Studio。现在,Visual Studio可以面向多个.NET版本,甚至可以将新的C编译器与旧的.NET框架(.NET 2.0中的lambda或扩展方法)混合使用。简单地说,C编译器版本与C语言版本相关。

您可以在项目文件中检查编译器版本(以XML方式打开),并且有项目元素的toolsversion属性。

在我的特定项目中有toolsversion="4.0",我的目标项目是.NET 2.0。这意味着我可以在旧框架中使用新的语言结构,这在VS2005中是不可能的。


要向Visual Studio指示要使用的语言版本,有一个名为/langversion的编译器选项
您可以在这里找到更多关于它的信息。
如本文所述,它也可以通过编程方式设置。< BR>编译器可以在不同版本的语言中编译,语言版本与框架的版本没有直接关系,但通常要使用一个语言特性,有一个最低限度的框架可以工作。< BR>几分钟前,我在vs 2015中编译了一个DLL,它使用C 6.0的字符串插值。

1
2
var version = 4;
var output = $"{version}";

并以框架4.0为目标。它编译并且工作得很好。这篇文章解释了版本纠结,但只针对旧的C版本。