The build machine where I work still uses the .Net 2.0 compiler.
I've set up Visual Studio to target the .Net Framework 2.0, but when I use the keyword var, it's compiling (since the compiler automagically change the type). But it breaks on the build machine compiler.
Is there a way to setup Visual Studio to break on those things, or even force it to use the 2.0 compiler, so that I won't make the mistake to break the build by using "too new" functionalities?
If I remember correctly, each version of .Net was tied to a specific version of DevStudio and it isn't possible to change this. If you need to compile for .Net 2 then you need the VS2005 compiler. One way to solve this is to use makefiles rather than the IDE to build the application and specify explicitly which compiler is used for each file.
Related
Here it was written that compilers of different versions are applied sequentially to build the latest version of compiler.
I don't want to use binaries provided by Microsoft. I want to have everything be compiled from source codes.
Which repositories I should compile exactly? Do they all have open source licenses?
The runtime and the compiler for .NET 5.0 are open-source. You can start by going to https://github.com/dotnet/runtime. However, building the runtime requires the compiler (which will be downloaded by running the build script). So there's little you can do to avoid getting binaries that were built by Microsoft. If you're afraid that they're fake (and in some way different from what you would get if you directly built everything from source) you'll probably have to go a different way.
Not entirely certain that this is even a valid question, however if I use VS2015 to open a solution that was originally created and maintained with VS2013, will it be compiled using the Roslyn compiler platform whenever built (within VS2015)?
The solution consists of WPF applications, Console applications, Web Applications, Windows Service applications and of course class libraries - so a good all round selection of options.
If this is not the case, how should I enable the Roslyn compiler for these projects?
Thanks.
If you open in VS2015, it will always use the Roslyn compiler to compile, regardless of the language version switch.
Using the /langversion switch simply tells the Roslyn compiler not to allow new features - it doesn't cause an older compiler to be used.
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
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.
I created new project in Visual Studio with target framework 2.0. But even if I left somewhere var keyword Visual Studio successfully compiles project. Is this the correct behavior as var is 3.0 feature? Is there any settings to prevent code with var to be compiled?
var is a feature of C# 3.0, but it doesn't require any framework features. In other words, it's absolutely fine to use within a project targeting .NET 2.0. The same is true of many other features - anonymous types, automatic properties, lambda expressions etc.
See my versions article for more information. (I need to update it for C# 4 at some point...)
If you want to restrict yourself to C# 2.0, you can specify the language version by clicking on "Advanced" in the Build tab of the project properties, IIRC. (It's definitely there somewhere, but I'd rather have a cup of coffee than check for the exact location right now.)
var is purely a compile-time feature, once the assembly is compiled, the compiler inserts the actual type and the fact that you had used var is "lost".
So a project that's targetting version 2.0 of the framework can still make use of the var feature, because it doesn't actually affect the outputted assembly in any way.
As long as your project will always be compiled with Visual Studio 2008 or newer, you're safe to use C# 3.0 features. The .NET 2.0 target only restricts what libraries you can use, not what language features.
Either do full text replace of var by 1var1 and manually replace them or use pre 3.0 versions of compiler.