Difference between C# compiler version and language version - c#

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.
Then I found out that the framework is not linked directly with the C# version, and on the same machine multiple C# compilers can be cohabitate, so probably the compiler and C# version should be the same.
Now I understand that the compiler version and the C# version are not the same...
Visual Studio Command Prompt (2010): C:\>csc
Microsoft (R) Visual C# Compiler version 4.0.30319.33440
for Microsoft (R) .NET Framework 4.5
Developer Command Prompt for VS 2013: C:\>csc
Microsoft (R) Visual C# Compiler version 12.0.30110.0
for C# 5
we can see that
- VS 2010 uses a compiler version 4.0 for the C#4 (?? I just can suppose it, because not explicitly mentioned);
- VS 2013 uses the compiler version 12.0 fo the C# 5 (this is explicitly mentioned)
Knowing that compiling using different language versions could bring different results to the user
Questions
How to find out what C# version (not the compiler one, but the language one) uses VS to build my concrete project?
Is there a strict, clear and transparent link between the C# compiler and language versions?
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?

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://learn.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.

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.

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

One way to tell the language version the compiler support is
csc -langversion:?
and get response like
Supported language versions:
default
1
2
3
4
5
6
7.0
7.1
7.2
7.3
8.0
9.0 (default)
latestmajor
preview
latest

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.

Related

In Which .Net Framework Version C# 7.2 is Available

I tried installing .net framework 4.7.2, still the target framework is empty in the project properties. The program I'm trying to run uses readonly struct, which is part C# 7.2.
Could you please guide me .Net Framework version has C# 7.2?
Language features are independent of .Net version (Framework/Core/Standard).
You will need to use a compiler that understands the newer language features. Assuming you're using Visual Studio 2017, you should update to latest version.
By default C# projects in Visual Studio use the latest major release of the language (which would be 7.0 as of this writing). To change this, open up the project's properties, select the Build page, click Advanced..., and under General set Langauge Version to "C# 7.2".
Per phuzi's comment mentioning this question, you might need to update to the latest Visual Studio in order to see this option.

Interdependencies of .NET runtime, C# language, compiler, visual studio

I want to use the new C#6 Language Features.
https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6
public class Foo {
public string ToolTip { get; set; } = "This is my toolip";
}
To that end I've upgraded all of our solutions to be VS2015 solutions.
I'm working in an MVC4 project targeting .NET4.
This compiles fine but fails to build on our build server which caused me to question exactly how all of the pieces fit together for roll-out.
It would seem to me that new language features would necessitate using the new compiler (Roslyn? which comes pre-installed with VS2015?).
The compiler would take my code and transform that into IL which gets executed by the run-time. So as long as the compiler supports the version of the .NET runtime I'm targeting, it seems my front-end webservers will not need to be upgraded for us to take advantage of C#6 features.
The point that makes me pause though is code that is JIT compiled, such as cshtml files.
Where can I go to read more about these inter dependencies?
C# Language
C# is a high-level language that gets transformed into MSIL by the compiler
MSIL is platform/language agnostic: C#, VBasic, F# all compile to the same MSIL
MSIL is executed by the .NET CLR
The C# language version is independent of the .NET CLR, so you do not need to update the CLR on the server running the code
In your project file, choose the version of the .NET framework to target which determines what MSIL is emitted by the compiler so it can be run on the target server
Certain language features in the future may be incompatible with old versions of the .NET Framework, but in that case your project will fail to build at compile time
New language features are only available with updates to the compiler(s)
ASP.NET is unique in that there is the compilation that happens during development, but also the run-time compilation of view files
Compiler
Starting in 2015, Roslyn is the new C# compiler
Prior to Roslyn, csc.exe was the main compiler, and it shipped with the .NET Framework
The ASP.NET runtime will compile views on-the-fly. To make it use Roslyn for this, install the CodeDOM Provider NuGet Package in your MVC project
Roslyn on GitHub
MSBuild
Suite of tools around building/deploying .NET applications
Leverages a specific compiler under the covers; I don't see a way to force MSBuild to use an older compiler
Used to ship with the .NET framework under C:/Windows/Microsoft.NET/Framework/v3.5/MSBuild.exe, leveraging csc.exe compiler
Starting in 2013, it started shipping with Visual Studio Releases under C:/Program Files (x86)/MSBuild/14.0/MSBuild.exe, leveraging Roslyn compiler
MSBuild on GitHub
Visual Studio 2015
The main code editing environment for C# and .NET applications
Installs .NET Framework 4.6.1
Installs MSBuild 14.0
Leverages MSBuild.exe to compile your C# code
Immediately allows writing C#6 code in the editor
.NET Framework/CLR
The .NET Framework is the Common Language Runtime (CLR) + managed libraries and tools
The CLR always ships with the .NET Framework major version
Targeting different versions of the .NET Framework gives you access to new/modfied libraries, as well as performance improvements when executing your MSIL code in the new CLR
Note: ASP.NET and ASP.NET MVC are part of the .NET Framework, so you
Current Versions
To use C#6 Language Features in MVC:
Install latest Visual Studio (this uses the latest version of MSBuild under the covers which leverages the latest compiler (Roslyn) to turn C# code into MSIL)
Add the new Roslyn CodeDOMProvider to your project via NuGet (this will get deployed to your web server as a referenced dll, and is what the ASP.NET runtime will use to compile views on the fly
Update the build server to have the latest version of MSBuild (and compiler) by installing the latest Visual Studio there
See MSDN for more details
The reason why the buildserver fails is, that it probably uses wrong verion of ms build.
Theres nothing special about roslyn. It's just set of libraries to work with code (parse, compile, etc). In vs2015 and corresponding msbuild is old C# compiler replaced by newer - roslyn.
If you want to know more, there is quite good pluralsight course https://www.pluralsight.com/courses/dotnet-compiler-platform-introduction
When it comes to build server, it depends on what build server you use. In general, you have to install vs2015 and instruct it to use the new msbuild. You can compile C# 6 for different runtimes.
For tfs2013 specify version and change build template TFS 2013 building .NET 4.6 / C# 6.0

Relationship between MSVC and .NET framework versions

This is a rather general question, a result of my confusion about how to compile GDAL using different versions of Microsoft Visual C++ (MSVC) and its C#-bindings. I understand that MSVC is a compiler and there are different versions (MSVC 2003, 2005, 2008, 2010, 2012). I also understand that C# is tied to the .NET framework, which is a software development framework that also comes in different versions (.NET 1.0 to 5.0).
I want to compile GDAL (because I want to use an extension not included in the SDK builds available here) to be used by C# (via its C#-bindings) using VS 2012, which version of MSVC would I have to use? I guess the answer is MSVC 2012 (same .NET framework version), but why actually? The GDAL build would create DLLs. Is the .NET framework not backwards compatible in the sense that I can use DLLs compiled with an older version of MSVC inside a C#-project that uses VS 2012?
Any enlightenment appreciated.
The relationship is largely irrelevant unless you're toying with C++/CLI (which it doesn't look like you are).
C# uses native DLLs either by using P/Invoke (aka DllImport) or through COM, it doesn't matter what compiler they were made with so long as the exports are in the right format (and they're in the right ISA for the executing .NET platform).
Using the same C++ compiler that VS ships with just saves you the trouble of hunting down alternative tools and simplifies your build process.

what .net version VS2005 use for C# project

I am porting a project built on VS2008 to VS2005 since the minor .NET version for us have to 2.0 instead of 3.5 and rest of our code is building on VS2005. So I modified the visual studio version from 2008 to 2005 at the .sln file
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
So I am able to load the .sln into the VS2005. I have some building problem, mainly the "var" and after I modified those lines with real data type, the code compiles and runs.
However at the project assembly reference. I found out that my code is still reference Linq which is from .NET 3.5:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll
When I open up the dialog to add new reference, I could see that the .NET version 2.0, 3.5 and even 4.0 (although the CLR runtime version is 2.0.50727 in most of cases. sometimes 1.x and sometimes 4.0, Linq's runtime version is 2.0.50727).
I thought that VS2005 only supports .NET 2.0 which seems not that case here. So I guess how can I make sure that my application would only require .NET 2.0 framework. Is it enough to make sure that I only reference .NET 2.0 and below reference?
As long as the target framework is .NET 2.0 and you don't reference any libraries that do target higher .NET framework versions, your app should run just fine on .NET 2.0.
That said, I believe Visual Studio 2008 supports multi-targeting, so you should be able to use VS2008 but still target .NET 2.0 as your output type. Additionally, VS2010 and VS2012RC also support .NET 2.0 only projects.
To answer the exact question in the title (for the benifit of those who find this page by its title) the .NET version used by default in Visual Studio 2005 is .NET v2.0.
You can still use VS2008. VS2008 fully supports 2.0-only projects (just change the project settings). When in 2.0 mode VS will disable any 3.0 and 3.5 assemblies as well as any C# language features that depend on 3.0 or 3.5 library classes (such as extension methods, but there is a workaround to get those working with 2.0).
I'll say that VS2010 also supports 2.0-only projects too.

Can I use all C# 4.0 features in a project that targets .Net 3.5?

Development Environment :
- VS2010
- .Net Framework 4.0, 3.5, 2.0
Staging and Production Environments:
- .Net Framework 3.5, 2.0
The project I'm working on is targeting .Net Framework 3.5. And today I used optional parameters feature, which is new to C#4, in this project and it worked fine. I think VS2010 is using C#4 compiler and is compiling the method with optional parameters to corresponding overloaded methods in IL.
I want to know if I can use all new C#4 features as well.
You cannot use is the dynamic feature. This relies on the C# runtime and DLR DLL's which are only available on the 4.0 version of the .Net framework. Versions of the DLR are available for 3.5 but I do not believe they are compatible with the one required by the C# compiler.
Additionally you cannot use NoPIA / Embedded Interop Types in a down targetted scenario. This feature requires CLR support that was added in 4.0.
What's great about down targeting in Visual Studio 2010 though is you don't have to be aware of every limitation. If your projects are set to down target 3.5 and you use an incompatible feature, Visual Studio will produce an error.
I bumped into this a couple of weeks ago actually. I used optional parameters even though the project targeted .net 3.5. You need to be very careful of this because if you install the application on a computer that only has .net 3.5 runtime installed then your program may not run. In my case, I used the optional params and the nightly build server only had 3.5 installed so the build failed.

Categories