dotnet / csharplang

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

C# 7.4, same as 7.3 but with NRT #2995

Closed carlreinke closed 4 years ago

carlreinke commented 4 years ago

Regarding "Embracing nullable reference types" by @MadsTorgersen

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 sure I'm not the first to say that this is not a nice position you've put library authors in. Dropping support for .NET Standard 2.0 is not going to viable for quite some time, so in order to embrace NRT, we have to do something that's explicitly unsupported (even though it "happens to" work if you keep away from other 8.0 features). If you want us to embrace it then support it.

NRT is a big deal in terms of the language evolution, so it makes sense that you'd want to increment the major version number if for no other reason than to showcase it. However, NRT is also a big deal for the .NET ecosystem, and as part of incrementing the major version number, you left .NET Standard 2.0 behind, which was a blow to anyone who must continue to support .NET Framework.

NRT doesn't require any runtime/framework changes, and it seems like it could, with a reasonable amount of effort, be backported to 7.x in Roslyn and be supported on .NET Standard 2.0.

So I'd like to propose that there be a C# 7.4, which would be 7.3+NRT. (Or you could name it 7.3+NRT if language versions don't have to be numbers.) No other features would be backported, even those that could be.

I realize there is no precedent for this, but I hope you'll give it a bit of consideration.

huoyaoyuan commented 4 years ago

I think the term "support" means "ensure everything can work". You can always explicitly turn on 8.0 and NRT by manually editing the project file. Everything that can work will work as expected.

NRT doesn't require any runtime/framework changes

It works much better with metadata changes:

carlreinke commented 4 years ago

You can always explicitly turn on 8.0 and NRT by manually editing the project file. Everything that can work will work as expected.

Not quite, support is lacking in Visual Studio.

It works much better with metadata changes:

  • The core lib get annotated.

Yes, that would be nice (although it doesn't affect a library's consumers), but in lieu of real annotations: https://github.com/tunnelvisionlabs/ReferenceAssemblyAnnotator

  • MaybeNullAttribute and others are available.

This one is pretty easy without support, as the attributes can be baked into your assemblies by using a NuGet package: https://www.nuget.org/packages/Nullable/

HaloFour commented 4 years ago

@carlreinke

Not quite, support is lacking in Visual Studio.

And given that the reason for not picking up that issue is that the team does not want to incur the engineering cost to make that scenario work I severely doubt they'll be willing to pick up the vastly larger engineering cost to backport the feature to a previous language and corresponding version of VS on top of it. NRTs are also going to evolve quickly over the next number of releases to clean up the myriad of known and identified problems with the feature, and backporting would more than double that effort.

canton7 commented 4 years ago

@carlreinke

Not quite, support is lacking in Visual Studio.

<Nullable> works just fine in SDK-style csproj files, whatever you're targeting. It's only old-style csproj files that have this problem.

You can (and really should) use SDK-style csproj files for all projects (WPF Framework projects can use MSBuild.Sdk.Extras). There are many advantages, and <Nullable> working correctly is one of them.

Exactly the same would apply if your proposed C# 7.4 were created: it would work for SDK-style csprojs, and not for old-style ones. Therefore everything you can do by setting the language version to 7.4, you can do by setting it to 8.

carlreinke commented 4 years ago

Except that it's explicitly unsupported.

canton7 commented 4 years ago

That's the official line on the whole of C# 8, yes. In practice, NRTs specifically have been carefully designed to work on older targets (with the compiler emitting attribute definitions into your assembly if it needs to, etc).

Although the official line has changed, the practical side remains exactly the same as before: new language features which don't rely on types from new targets (or which can use types from NuGet packages) will work fine on old targets. We just lose the ability to shout at Microsoft if something we think should work in fact doesn't in some edge case. If something from a new language version compiles on an old target, it's fine.

A statement from someone with authority saying that NRTs work on older targets would be a lot less effort than an entirely new language version...

AartBluestoke commented 4 years ago

one of the reason that c#8 isn't back-ported is the compatibility of the other features, not just NRT - https://github.com/dotnet/csharplang/issues/2877#issuecomment-540011743 and the following comments outline the compatibility issues between c#8 and .net Framework (not quite the question asked, but basically the same issue)