Closed Taudris closed 3 years ago
Apparently NRT depends on the C# 8.0 compiler for things like nullable generic type arguments. The attributes that are compiler-generated, Nullable(byte/byte[])
and NullableContext(byte)
, are quite difficult to annotate code with by hand. So one must either use an unsupported TargetFramework
/LangVersion
combination, or contend with incomplete nullable support.
It would be nice to at least have the option for the latter guarded by a #define
and some documented caveats.
Hey there!
As you wrote, manually annotating the attributes with Nullable/NullableContext
is not something I would want to try/do as that is too complex and fragile for my taste.
A possible solution would be to nest the #nullable enable/#nullable restore
s in a NULLABLE_ATTRIBUTES_DISABLE_NULLABILITY
preprocessor variable. That would allow you to manually remove them (and just end up with ambiguous nullability). At the moment, not a single attribute uses a single ?
anyway, so the effort would be manageable.
I'm not so sure about whether I want to make this change though. I would generally assume users of the package to use C# 8.0+ (it's even a requirement in the README) and I'm not certain whether I want to relax that requirement.
Since you already wrote about the issue with Nullable/NullableContext
: Do you think that you will continue with your plan to migrate your company's files to NRTs? You will, after all, have the same issue mentioned above with your custom code and it already sounded like this is not really an option for you either.
If you do continue, is it an option for you to simply copy the attribute files to your project(s) manually and remove the nullable annotations? Then you would not depend on any change in this package.
I tried doing exactly that. While it is compatible and does seem to work, it raises the question of complexity vs usefulness. You're getting an unknown subset of features, potentially breaking IDEs which depend on NullableAttribute
and NullableContextAttribute
(VS2019 currently treats referenced projects that don't have NRT enabled in an NRT project as having all non-nullable references - I hope/assume this is a bug that'll get fixed using information from these attributes), and creating an extra burden for other devs to learn on top of learning regular NRT.
I ended up multitargeting netstandard2.0 and 2.1, adding a preprocessor definition NULLABLE_ENABLED, and gating the new syntax with it. It's real ugly, but it's the only way to be 100% safe while getting NRT. I just wish the preprocessor was enough more powerful in some way to help deal with it.
I'm trying to create a NuGet package which contains 100% manual NRT attributes (with no C# 8.0 syntax) so that I can multitarget
netstandard2.0
andnetstandard2.1
, remain in an MS-supported configuration (employer requirement), and get correct nullability warnings in projects which use C# 8.0+.When I try to build against
netstandard2.0
, I get build errors on the generated .cs files in theobj
folder because they include the#nullable
preprocessor statement. If this preprocessor statement was not present (and the attributes had their own explicit annotations, if that's possible/needed), the files would otherwise compile.Do you think you could make this change?