Difference between C# compiler version and language version

前端 未结 4 1521
天命终不由人
天命终不由人 2020-12-24 08:08

There was time I thought that the Framework version and the C# version are the same things, so once you install the next Framework version on the computer, you should use it

相关标签:
4条回答
  • 2020-12-24 08:30

    As nobody gives a good enough answer, I will have a try now.

    First, C# has its version history published by Microsoft now (coming from MVP posts obviously),

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

    So you can easily see what new features are added for each new releases.

    Second, we will talk about the compiler releases, which initially were part of .NET Framework.

    Below I list a few milestones (might not be 100% correct, and some versions might be skipped),

    • csc.exe 1.0 (?) for .NET Framework 1.0 (implements C# 1.0).
    • csc.exe 2.0 (Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.8745) for .NET Framework 2.0 (implements C# 2.0, as well as 1.0 for compatibility).
    • csc.exe 3.5 (Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.8763) for .NET Framework 3.5 (implements C# 3.0, and older versions).
    • csc.exe 4.0 (?) for .NET Framework 4.0 (implements C# 4.0, and older).
    • csc.exe 4.x (like Microsoft (R) Visual C# Compiler version 4.7.2053.0) for .NET Framework 4.5 and above (implements C# 5.0, and older). Note that the version numbers vary a lot (from 4.x to 12.x) based on the .NET Framework on your machine (4.5.0 to 4.7.1).

    Then Microsoft made the old csc.exe obsolete (as they were native executable), and shipped Roslyn based compiler instead (though still csc.exe). In the meantime, C# compiler is no longer part of .NET Framework, but part of VS.

    It was the same time, that C# compiler, language version, and .NET Framework are fully decoupled, so that you can easily use multi-targeting.

    • Roslyn csc.exe 1.x (?) implements C# 6.0 and older. Shipped with VS2015.
    • Roslyn csc.exe 2.x (like Microsoft (R) Visual C# Compiler version 2.4.0.62122 (ab56a4a6)) implements C# 7.x and older. Shipped with VS2017.

    Ok, enough background. Back to your questions.

    Q1: How to find out what C# version (not the compiler one, but the language one) uses VS to build my concrete project?

    Answer: You can easily see from project settings that what language version is used.

    If you don't choose an explicit version, it can automatically use the latest version supported by the csc.exe compiling the project.

    Note that @Servy commented under @DaniloCataldo's answer about the langversion switch with more details. That switch has its design goals and limitation. So for example even if you force Roslyn 2.x compiler to compile your project based on C# 4.0, the compiled result would be different from what C# 4.0 compiler does.

    Q2: Is there a strict, clear and transparent link between the C# compiler and language versions?

    Answer: Please refer to the background I described above, I think that already answered this part. There is a strict, clear and transparent link.

    Q3: Can I indicate to Visual Studio (in case of migration issues from one Studio version to another) to use different compiler version for my concrete solution?

    Answer: A Visual Studio release (like VS2019) sticks to an MSBuild release (16.x), so a dedicate version of C# compiler. So in general Q3 is duplicate to Q1, as you can only change language version.

    There are a bunch of NuGet packages to override C# compiler used by a project, such as https://www.nuget.org/packages/Microsoft.Net.Compilers.Toolset. However, Microsoft states that "Using it as a long term solution for providing newer compilers on older MSBuild installations is explicitly not supported", so you really shouldn't explore that route.

    0 讨论(0)
  • 2020-12-24 08:41

    Just to add to the previous answer. You should be aware that while the C# language and the C# compiler are separate from .Net framework, they still depend on it.

    For example, the C# 5 has await/async language feature, but you can't use it with the .Net 4, at least not without some extra actions and nuget packages.

    On the other hand, you still can use the nameof or null propagation features of C# 6 with the .Net 4.0 because they are implemented purely by compiler

    0 讨论(0)
  • 2020-12-24 08:42

    In the past Visual Studio 2005 was fixed only to one .Net version and C# compiler delivered with this version. In case you want use newer version of VS you have to switch Visual Studio as well. Now Visual studio can target to more than one .Net version and it can even mix new C# compiler with old .Net framework (lambdas or extension methods in .Net 2.0). Simply C# compiler version is related to C# language version.

    You can check your compiler version in project file (open it as xml) and there is ToolsVersion attribute of Project element.

    In my specific project there is ToolsVersion="4.0" and my target project is .Net 2.0. It means I can use new language construct in old framework which is not possible in VS2005.

    0 讨论(0)
  • 2020-12-24 08:49

    To indicate to Visual Studio which language version to use there's a compiler option called /langversion
    You can find more about it here.
    It can be set programmatically too, as stated here.
    The compiler can compile in different versions of the language, the language version is not directly related to that of the framework, but often to use a language feature there's a minimum framework for which it can work.
    Just few minutes ago I have compiled in VS 2015 a dll which uses the string interpolation of c# 6.0

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

    and has the framework 4.0 as target. It compiles and works fine. This post explains versions entanglement, but only for older c# versions.

    0 讨论(0)
提交回复
热议问题