【问题标题】:Difference between C# compiler version and language versionC#编译器版本和语言版本的区别
【发布时间】:2014-05-13 22:35:10
【问题描述】:

有段时间我觉得Framework版本和C#版本是一样的东西,所以一旦你在电脑上安装了下一个Framework版本,就应该使用它。

后来发现框架没有直接和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.0
适用于 C# 5


我们可以看到
- VS 2010 使用 C#4 的编译器版本 4.0(??我只是可以假设,因为没有明确提及);
- VS 2013 使用 C# 5 的编译器版本 12.0(这是明确提到的)

知道compiling using different language versions could bring different results给用户

问题

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

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

  • 我能否指示 Visual Studio(如果从一个 Studio 版本迁移到另一个版本时出现迁移问题)为我的具体解决方案使用不同的编译器版本?

【问题讨论】:

  • 鉴于编译器是将一堆文件作为输入并输出另一个文件的软件,而 c# 基本上是一种规范,因此它们的版本控制方式不同并不让我感到惊讶。跨度>
  • @Thorsten Dittmar :不。同一个框架可以使用不同的 C# 版本(编译器)
  • @Default:相关问题将 .NET Framework 版本与 C# 版本相关联。我问的是编译器和语言之间的相同链接,不关心框架。
  • @ThorstenDittmar 查看问题中的链接。
  • 它是 VS2013 中重要的 msbuild 重组的一部分。键入“where csc.exe”以查看发生了什么。使用 Visual Studio 命令提示符之类的命令的目的是让 Microsoft 担心是否正确。

标签: c# .net visual-studio-2010 compiler-construction visual-studio-2013


【解决方案1】:

过去,Visual Studio 2005 仅被修复为一个 .Net 版本和随此版本提供的 C# 编译器。如果您想使用较新版本的 VS,您还必须切换 Visual Studio。现在 Visual Studio 可以针对多个 .Net 版本,它甚至可以将新的 C# 编译器与旧的 .Net 框架(.Net 2.0 中的 lambda 或扩展方法)混合使用。只是C#编译器版本与C#语言版本有关。

您可以在项目文件中查看您的编译器版本(以 xml 格式打开),并且 Project 元素有 ToolsVersion 属性。

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

【讨论】:

  • 我不认为更改工具版本会更改编译器版本,我只是对其进行了测试,将工具版本设置为较低的数字并没有改变 test program 的输出,它应该在下面显示不同的行为旧的编译器。
  • 感谢您的回答。是否有任何参考说明编译器和语言版本之间的具体关系?比如说,我想使用 C#5,我应该针对哪个编译器版本?
  • @Scott Chamberlain 看来VS2010自动将此属性升级到4.0:stackoverflow.com/questions/2770361/…
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

    为了向 Visual Studio 指示要使用的语言版本,有一个名为 /langversion 的编译器选项
    您可以在here 找到更多相关信息。
    它也可以通过编程方式设置,如here 所述。
    编译器可以编译不同版本的语言,语言版本与框架的版本没有直接关系,但通常要使用一种语言特性,有一个最小的框架可以工作。
    就在几分钟前,我在 VS 2015 中编译了一个使用 c# 6.0 的字符串插值的 dll

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

    并以框架 4.0 为目标。 它编译并且工作正常。 This post 解释了版本纠缠,但仅适用于较旧的 c# 版本。

    【讨论】:

    • langversion 开关不会更改实际的语言版本(与名称所暗示的相反)。它只会导致某些功能的使用导致编译时错误。除了添加新功能之外,C# 版本之间还有许多变化,因此在 langversion 开关设置为 3.0 的 C# 7 编译器上编译的代码与在 C# 3.0 编译器上编译的代码的行为将不同。
    【解决方案4】:

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

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

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

    因此您可以轻松查看每个新版本添加了哪些新功能。

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

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

    • csc.exe 1.0 (?) 用于 .NET Framework 1.0(实现 C# 1.0)。
    • csc.exe 2.0(Microsoft (R) Visual C# 2005 编译器版本 8.00.50727.8745)用于 .NET Framework 2.0(实现 C# 2.0 以及 1.0 以实现兼容性)。
    • csc.exe 3.5(Microsoft (R) Visual C# 2008 Compiler 版本 3.5.30729.8763)用于 .NET Framework 3.5(实现 C# 3.0 和更早的版本)。
    • csc.exe 4.0 (?) 用于 .NET Framework 4.0(实现 C# 4.0 及更早版本)。
    • csc.exe 4.x(类似于 Microsoft (R) Visual C# Compiler 版本 4.7.2053.0),适用于 .NET Framework 4.5 及更高版本(实现 C# 5.0 及更早版本)。请注意,根据您计算机上的 .NET Framework(4.5.0 到 4.7.1),版本号有很大差异(从 4.x 到 12.x)。

    然后,Microsoft 废弃了旧的 csc.exe(因为它们是本机可执行文件),并提供了基于 Roslyn 的编译器(尽管仍然是 csc.exe)。同时,C#编译器不再是.NET Framework的一部分,而是VS的一部分。

    同时,C#编译器、语言版本和.NET Framework完全解耦,让你可以轻松使用多目标。

    • Roslyn csc.exe 1.x (?) 实现 C# 6.0 及更早版本。随 VS2015 提供。
    • Roslyn csc.exe 2.x(类似于 Microsoft (R) Visual C# Compiler 版本 2.4.0.62122 (ab56a4a6))实现 C# 7.x 及更早版本。随 VS2017 提供。

    好的,背景足够了。回到您的问题。

    Q1:如何找出哪个 C# 版本(不是编译器版本,而是语言版本)使用 VS 构建我的具体项目?

    回答:从项目设置中可以很容易看出使用的是什么语言版本。

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

    请注意,@Servy 在@DaniloCataldo 的回答下评论了有关langversion 开关的更多详细信息。该开关有其设计目标和局限性。因此,例如,即使您强制 Roslyn 2.x 编译器基于 C# 4.0 编译您的项目,编译结果也会与 C# 4.0 编译器所做的不同。

    Q2:C#编译器和语言版本之间是否有严格、清晰、透明的联系?

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

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

    答案:Visual Studio 版本(如 VS2019)坚持 MSBuild 版本 (16.x),因此是 C# 编译器的专用版本。所以总的来说 Q3 与 Q1 重复,因为您只能更改语言版本。

    有一堆 NuGet 包可以覆盖项目使用的 C# 编译器,例如https://www.nuget.org/packages/Microsoft.Net.Compilers.Toolset。但是,Microsoft 声明“明确不支持将其用作在较旧的 MSBuild 安装上提供较新编译器的长期解决方案”,因此您真的不应该探索这条路线。

    【讨论】:

    • 已经有一段时间了,但感谢您的详细回答。您在回答问题 3 时写道,与 Q1 重复,但我认为它不能回答问题。我还是不明白如何控制编译器版本?例如,我想要一个更新的 VS 版本来编译旧的编译器版本。这可能吗?如果可以,怎么做?谢谢
    • @MaorB 只有 C++ 项目从头开始设计以支持该场景。 C# 项目不是。
    • 好的,谢谢。因此,如果我确实想使用我第一次创建应用程序时使用的相同编译器版本 tjat 进行编译,我需要使用我最初使用的相同 VS 版本,对吧?
    • @MaorB 对。您最好使用旧的 VS 版本,以使您的环境足够稳定。较新的 VS 版本绑定到较新的 MSBuild 版本和 C# 编译器版本,因此无法从那里返回。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-11
    • 1970-01-01
    • 2014-08-22
    • 1970-01-01
    相关资源
    最近更新 更多