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

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

Related

What's the difference between using dotnet and MSBuild for building .NET applications?

I've just had to do some builds without using Visual Studio for the first time, and clearly there is a gap in my knowledge regarding MSBuild and the build process.
So, what are the differences between the two build processes below?
Option 1:
dotnet build C:\Dev\trunk\Mvc.sln
This option uses "Build Engine version 16.8.3+39993bd9d for .NET" - I presume this means this way can be used for .NET Core as it has no reference to "Framework"?
Option 2:
msbuild C:\Dev\trunk\Mvc.sln
This option uses "Build Engine version 16.8.2+25e4d540b for .NET Framework".
My assumption was that the "dotnet build" command was just a shorthand way of using MSBuild. However, the logging provided by both is pretty different and they both produce different results.
Roslyn -- the C# compiler platform -- is a .NET Standard 2.0 library, meaning that it can run on both .NET Framework 4.6.1+ and .NET Core 2.0+(1).
Visual Studio, which includes MSBuild, runs on .NET Framework. When you build a project using Visual Studio (or directly using MSBuild), it runs Roslyn on .NET Framework. Visual Studio knows how to process both SDK-style csprojs and the legacy non-SDK-style csprojs, and invoke Roslyn accordingly. The version of Roslyn which is used is tied to the Visual Studio version.
dotnet build is a separate tool, and is a .NET Core application. It knows how to build SDK-style csprojs only, and it does this by running Roslyn on .NET Core. Roslyn is distributed with the .NET Core SDKs, and dotnet build loads Roslyn from one of these installed SDK versions (normally the latest).
These two ways of building a C# project are more-or-less equivalent, and they invoke the same compiler code. However, they differ on where they can run (Visual Studio is .NET Framework and Windows-only, dotnet build is .NET Core and can run on multiple platforms), and whether they can build legacy non-SDK-style csprojs. dotnet build is also a bit nicer to use from the command-line.
Note that the runtime which Roslyn is loaded into has no bearing on the compiled IL which Roslyn can emit: Roslyn running on .NET Framework can emit IL which is executed by .NET Core just fine, and vice versa.
If you are using analyzers which target .NET Core (unlikely, as Analyzers are encouraged to target .NET Standard 2.0), these will only run from dotnet build.
(1) I'm using ".NET Core" to refer to both .NET Core and .NET 5+.

Build server of an old ASP.NET 4 application fails building new C# 7, but it works in development

I recently start to work on a legacy ASP.NET codebase based on .NET framework 4.0. We managed to pass everything from Visual Studio 2012 to VS 2017, updated the build server with a new version of Jenkins and installing .NET framework 4.7.x.
Locally we can write C# code of the newest version (7.3) and the build works (VS doesn't use MSBuild if I remember right), but when we deploy on the build server the build fails because there MSBuild cannot recognize constructs newer than C# 4.0. To avoid mistakes I fixed the lang version to 4.0 (advanced build properties on projects), so if I write too new C# VS blocks me in dev, but we would like to start using new C#.
We also tried to fix C# 7.3 directly in the project (<LangVersion>7.3</LangVersion> in PropertyGroup inside csproj) and the but ToolsVersion property of Project element (csproj) to 14.0, but then building we MSBuild fails with the error:
CS1617: Invalid option ‘6’ for /langversion; must be ISO-1, ISO-2, 3,
4, 5 or Default
Here it's explained that what I want to do it is possible: https://www.dotnetcurry.com/dotnet/1427/build-apps-different-dotnet-framework-versions
No matter which .NET framework version we target in the project, the
C# language version in use will not change. That’s fine because the
vast majority of language features that were introduced in later
versions of the language don’t depend on the CLR or specific APIs.
They are only syntactic sugar and the bytecode generated by the
compiler will still work in .NET framework 2.0.
Anyone have an idea of what mistake are we doing?
The problem was that on the build server MSBuild wasn't properly installed and build scripts got an old one.
Installing Visual Studio 2017 Build tools and fixing the path on the script we solved.
After we had the problem "The “GetReferenceNearestTargetFrameworkTask” task was not found" we solved like explained here: The "GetReferenceNearestTargetFrameworkTask" task was not found
(the right answer depends on what strategy have you used to install VS Buld tools).

Difference between C# compiler version and language version

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.

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.

Categories