dotnet / csharplang

The official repo for the design of the C# programming language
11.52k stars 1.03k forks source link

[Question]: Plans for tying the language version tied to the target platform #3695

Closed MichaelKetting closed 4 years ago

MichaelKetting commented 4 years ago

While checking up on the design notes, I saw the followign in https://github.com/dotnet/csharplang/blob/master/meetings/2020/LDM-2020-07-01.md

In .NET Framework and .NET Core prior to 2.0, a call to M will print 0. However, .NET Core fixed this API in 2.0 to correctly call the parameterless constructor of a struct if one is present, and since we now tie language version to the target platform there will be no supported scenario with this bug.

Up until C# 8.0 it was possible to use syntax features of C# 8 and everything that was just sugar worked in .NET Framework and .NET Standard 2.0. When you provide the types, even nullable reference types work in .NET Framework.

Am I reading this correct, that the intention is to block new syntax features for code bases that do not target .NET 5 or later and if so, which C# version will introduce this? Right now, I'm mostly concerned about null-checks, since this is a feature I intended to apply to my entire code base once it's available. There's of course a bunch of other features, too, such as target-typed new, pattern matching improvements, local function improvements, which do not depend on the underlying platform.

When maintaining a code base that multi-targets .NET Framework, .NET Standard 2.0 and .NET 5 (or possibly just .NET Standard 2.0, if possible based on the dependencies), it would be very unfortunate to be blocked from using the latest syntactical sugar. Some code bases must be mainteined for 10+ years and denying the developers the latest features is not feasable in terms of employee satisfaction.

Could you please either expand on this or point me to an ongoing discussion where this was introduced / discussed, because right now it creates a great deal of uncertainty on how to maintain existing code bases, projects, and products.

Thanks, Michael

KalleOlaviNiemitalo commented 4 years ago

C# language versioning (since https://github.com/dotnet/docs/pull/17174):

C# 8.0 (and higher) is supported only on .NET Core 3.x and newer versions.

Embracing nullable reference types (November 27th, 2019):

You also have to set the language version to C# 8.0, of course, and that is not a supported scenario when one of the target versions is below .NET Core 3.0.

An update to C# versions and C# tooling (February 27th, 2019):

Because C# 8.0 has been built for .NET Core 3.0 and .NET Standard 2.1, it will not be supported outside of .NET Core 3.0 and any platform implementing .NET Standard 2.1.

Building C# 8.0 (November 12th, 2018):

For this reason, using C# 8.0 is only supported on platforms that implement .NET Standard 2.1.

jnm2 commented 4 years ago

The official position (https://devblogs.microsoft.com/dotnet/building-c-8-0/) is that C# 8 only supported on platforms that implement .NET Standard 2.1. This will perpetually exclude .NET Framework because no future version is planned. This also excludes ever using C# 8 with .NET Standard 2.0 in spite of the fact that .NET Standard 2.0 is the current Microsoft guidance for open-source libraries.

https://devblogs.microsoft.com/dotnet/embracing-nullable-reference-types/:

You also have to set the language version to C# 8.0, of course, and that is not a supported scenario when one of the target versions is below .NET Core 3.0. However, you can still do it manually in your project settings, and unlike many C# 8.0 features, the NRT feature specifically happens to not depend on specific elements of .NET Core 3.1. But if you try to use other language features of C# 8.0 while targeting .NET Standard 2.0, all bets are off!

I'm not aware of any ongoing discussions. Here's an old one: https://github.com/dotnet/project-system/issues/5551

This has led to some open-source projects preferring to continue providing .NET Framework or .NET Standard 2.0 builds and deciding to stay off of C# 8 entirely.

Personally, I find it an oversimplification. I'm using https://github.com/tunnelvisionlabs/ReferenceAssemblyAnnotator so that even the .NET Standard 2.0 and .NET Framework BCLs have nullability annotations for things like string.IsNullOrEmpty and Debug.Assert to be recognized by the compiler. Every version of C# that has been released has depended on some framework types that you could declare yourself. C# 8 has only one thing that is a new kind of dependency: a platform dependency for the Default Interface Methods feature. As long as you follow the compiler errors that prevent you from using DIMs on an unsupported target framework, there are no further concerns that I'm aware of for using C# 8 on frameworks other than netcoreapp3.1+ and netstandard2.1+.

There's every chance that I'll be using C# 9 on .NET Framework, or .NET Standard 2.0 at least, in spite of the fact that this is already labeled unsupported.

quinmars commented 4 years ago

It's a pity that you are asked to embrace nullable reference types on the one hand, and on the other hand this is offically only possible if you drop netstandard2.0 (and so .NET framework) support. If you want to support both .NET5 with NRT and netstandard2.0, you are forced to go the inofficial way which is poorly documentated because it is not official.

KalleOlaviNiemitalo commented 4 years ago

Old discussion in https://github.com/dotnet/csharplang/issues/2995 and https://github.com/dotnet/csharplang/issues/2877.

333fred commented 4 years ago

Closing out. I believe the question has been answered, and there are other threads for further discussion.

MichaelKetting commented 4 years ago

@333fred Please reopen this issue, my question is not being answered by the links provided from @KalleOlaviNiemitalo.

I specifically asked if there are plans to prevent us from using any C# 9 features when targeting .NET Framework or .NET Standard, etc. Right now, you can do this with C# 8 and it is not clear if this will be prevented in future versions of C# and if so, starting with which version.

Yes, I'm perfectly aware of the official policy and did not feel the need to re-state this. I did not find official information on plans by the Roslyn team on whether to introduce a guard / block to actively prevent setting the language level to C# 9 and still target .NET Framework or .NET Standard. I am perfectly happy staying away from features that will not work due to constraints in the runtime, I just wish to use the features that do work.

@jnm2 thanks for the link to the annotator. We've been working on something similiar. It does seem we're in the same boat and would be left stranded if using C# 9 language together with .NET Framework or .NET Standard resulted in a compiler error.

333fred commented 4 years ago

I specifically asked if there are plans to prevent us from using any C# 9 features when targeting .NET Framework or .NET Standard, etc.

There are no such plans. Just as with C# 8, this will not be an officially supported feature. But language features that do not depend on framework changes will likely work just fine.

MichaelKetting commented 4 years ago

@333fred Thank you for clearing this up. Much appricated!