Sideeffects of using an older .NET version with a newer C# version - c#

I wrote some code in .NET Project on a windows 10 machine with visual studio 2017.
The target framework ist 4.5.2. and the used C# version is default (running the csc tool under "C:\Windows\Microsoft.NET\Framework\v4.0.30319" shows C# 5.
I have used a feature from C# 6. The Monadic null checking (https://damieng.com/blog/2013/12/09/probable-c-6-0-features-illustrated).
and the compiler doesn't complain about it.
Is that a normal bhaviour or am I missing something? Shouldn't the compiler complain about it?

What you're missing is that the C# compiler being used isn't the csc.exe you found. Visual Studio comes with its own C# compiler which supports C# 6 (and later, depending on the exact version of VS you've got installed).

C# language version is decided by Visual Studio, not by .Net Framework.
As long as your Visual Studio version supports the C# version you will not face any error.
Configuring Language version in Visual Studio: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/configure-language-version

Related

Can C# 11 be installed in Visual Studio 2019 or should I download VS 2022?

I would like to write some console apps using C# 11. I know that it can be only with .NET 7x. If I write
<TargetFramework>netcoreapp7</TargetFramework>
in my .csproj file, I will get NETSDK1045 instead of running. But "file" (type modifier) is useful.
As written in the .NET 7 release notes for .NET 7 support in Visual Studio you need to install 17.4+ version:
You need Visual Studio 17.4 latest preview to use .NET 7.0 on Windows. On macOS, you need the latest version of Visual Studio for Mac. The C# extension for Visual Studio Code supports .NET 7.0 and C# 11.
You can try using 2019 version but some features even for .NET 6 (see this answer) will not work correctly (note that building and running from command line via dotnet ... still should work correctly if appropriate SDK is installed).
So in short - install the latest VS 2022.
There's no inherent downside to upgrading your Visual Studio (as long as your tools are compatible). Within it you can still develop for older versions.
As mentioned by rbdeenk, you have to upgrade Visual Studio as per this link: https://dotnet.microsoft.com/en-us/download/dotnet/7.0

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).

How to update C# Compiler to version 6-Visual Studio Community 2015

I have been trying to update my C# compiler after getting the below error when trying to compile a file:
This compiler is provided as part of the Microsoft (R) .NET Framework, but only supports language versions up to C# 5, which is no longer the latest version. For compilers that support newer versions of the C# programming language, see http://go.microsoft.com/fwlink/?LinkID=533240
I downloaded Roslyn as directed (not sure if it needed to go in a particular folder with the visual studio files) but didn't get any further with it.
I also found guidance to run the below command in visual studio :
Install-Package Microsoft.Net.Compilers
But this also generates errors when attempting, regardless of whether or not a solution is open.
I'm trying to get the compiler to update to version 6, I feel like this should be very simple but I haven't gotten anywhere with the advice I've researched. Any ideas?
If you are using Visual Studio 2015 Community Edition you should already have the C# 6 compilers since they shipped with Visual Studio 2015.
I just installed the RTM version of Visual Studio 2015 Community Edition on a clean system. The csc.exe compiler it installs (under C:\Program Files (x86)\MSBuild\14.0\Bin\ reports itself as Microsoft (R) Visual C# Compiler version 1.0.0.50618. The file's modified date is 6/21/2015.
The help section on the langversion switch reports /langversion: <string> Specify language version mode: ISO-1, ISO-2, 3, 4, 5, 6, or Default
This compiler is provided as part of the Microsoft (R) .NET Framework, but only supports language versions up to C# 5, which is no longer the latest version. For compilers that support newer versions of the C# programming language, see http://go.microsoft.com/fwlink/?LinkID=533240
The wording of this warning message suggests that you are using a version of the C# compiler shipped with the .NET Framework rather than one that was shipped with Visual Studio 2015.

Difference compilation VS 2015 and VS 2010

I have a free .Net 4.0 app that protect with Eazfuscator v3.3 (last free version). All the classes in my single project app are internal. I use symbol encryption to encrypt class names, methods and members. Up until now, everything was encrypted
Up until now, I was using VS 2010, and everything worked fine. I switched to VS 2015, still targeting .Net 4.0 framework. Once the code is compiled and obfuscated, using reflector I can clearly see class names in clear (but methods and members are still encrypted)
Is there anything different between VS 2010 compilation and VS 2015 compilation if both target .Net 4.0?
Thanks
VS 2015 uses Roslyn compiler. It produces different instructions and metadata and this affects the analysis engine in Eazfuscator.NET 3.3.
Eazfuscator.NET 3.3 cannot work with assemblies produced by VS 2015 or newer.
The support for Visual Studio 2015 was added in Eazfuscator.NET 4.9, so you need at least that version to successfully obfuscate the assemblies produced by Roslyn compilers.

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.

Categories