How to treat ALL C# 8 nullable reference warnings as errors?
Asked Answered
C

4

71

Using Visual Studio 2019 v16.3.2 with a .NET Core 3.0 project set to C# 8 and nullable reference types enabled.

<PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <LangVersion>8.0</LangVersion>
    <Nullable>enable</Nullable>
</PropertyGroup>

If I set it to treat all warnings as errors:

warnings as errors radio button selected

<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<WarningsAsErrors />

It reports other warnings as errors. For example, CS0168 The variable 'x' is declared but never used is reported as an error. But all the nullable reference warnings are still reported as warnings. For example, CS8600 Converting null literal or possible null value to non-nullable type. is still reported as a warning.

How do I treat all nullable reference warnings as errors?

Note: even setting CS8600 specifically to be treated as an error doesn't cause it to be reported as an error. If that worked, it still wouldn't help with treating them all as errors because there are so many.

Edit: setting specific warnings to be treated as errors puts <WarningsAsErrors>CS8600;CS8602;CS8603</WarningsAsErrors> in the csproj and doesn't work.

Calculous answered 2/10, 2019 at 3:52 Comment(3)
I think your VS has problem. Same config work for me. Please try to reinstall your VSTsarevna
are you building the project to get these warnings/errors, or is the problem happening in the editor window? there seem to be lots of synchronization issues with the compiler that's running in the code window, but it shouldn't be able to get past an actual build process.Prisoner
So confused, was anybody actually having so many problems with Null Reference Errors that all this was required? It was just never a problem for any codebase I've worked on.Siana
A
114

It is now possible to treat all nullable-related warnings as errors without explicitly specifying them all. To achieve this, you have to set <WarningsAsErrors>Nullable</WarningsAsErrors> in your *.csproj file [source].

Full example:

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <Nullable>enable</Nullable>
    <WarningsAsErrors>Nullable</WarningsAsErrors>
  </PropertyGroup>
</Project>

Aristippus answered 31/5, 2020 at 13:25 Comment(11)
be careful. You will have to treat all not null properties with fake init = null!; Is there any way to add all and then exclude certain ones?Delectable
The question is explicitly about treating all nullable warnings as errors.Aristippus
@Delectable Other than that, my approach to introduce the nullable feature in existing code bases is to use the #nullable enable pragma for new/changed files. The other way around could be to globally enable it but opt-out for your special files with #nullable disable.Aristippus
Not sure how can it help with all that annoying places with ` = null!`Delectable
@SerjG: I don't get it: Why would you have such properties? Either it is nullable or it is not and then it must be initialized in some way, either directly in its declaration or in the constructor or by a helper method called in the constructor (use attribute MemberNotNull) or it gets initialized through a lazy getter and then the property is non-nullable with attribute AllowNull for the setter (but declared on the property) if it is allowed to clear the cached value and have it recreated by the next getter call.Linzer
@SerjG: Or you have properties where it is invalid to assign null which do not need to be initialized, then that would be a nullable property with attribute DisallowNull for the setter (but declared on the property).Linzer
@Linzer we have a lot of JSON models which will ne initialized one deserialized. And yes, we are too lazy to create .ctors.Delectable
@SerjG: But would that not be a classic usage of nullable reference types? Each property may be null, may have been serialized as null, may not have been serialized because the model changed after the serialization or the JSON data was changed manually etc.? I personally would make all value- and reference types of DTO properties nullable (the nullalbe value types only of new or private interfaces as it breaks the existing contract), and the method receiving the DTO validates whether all mandatory properties are initialized and contain sensible values...Linzer
@Linzer no it's not. We mark with ? properties which can be deserialized as null. Validation is not enough to make analyzer think that value is presented. So we have to use ! or transform to some other object which has not null properties. Both ways are annoyingDelectable
@SerjG: But that concept does not work imho: What if a non-nullable reference property is not included in the serialized JSON for whatever reason? It becomes null when deserialized and is passed on as null but you guarantee it is non-null in your contract.Linzer
@Linzer yes. It's a trade-off between a lot of null checks and correct nullability usage. Also we have validation for required properties and should not work with invalid objectsDelectable
D
15

I would suggest to use this solution. It mentions all 3 errors and IMHO better solution

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <LangVersion>8.0</LangVersion>
    <WarningsAsErrors>CS8600;CS8602;CS8603</WarningsAsErrors>
  </PropertyGroup>
</Project>

screen


Update:

We have this list now: <WarningsAsErrors>CS8600;CS8601;CS8602;CS8603;CS8613;CS8625;CS8629;CS8614;CS8619;CS8633</WarningsAsErrors>

Update 2021-04:

We have this list now: <WarningsAsErrors>CS8600;CS8601;CS8602;CS8603;CS8604;CS8613;CS8614;CS8619;CS8620;CS8622;CS8625;CS8629;CS8633,CS8767</WarningsAsErrors>

Update 2023-05:

We have this list now: <WarningsAsErrors>CS8600;CS8601;CS8602;CS8604;CS8613;CS8614;CS8619;CS8620;CS8622;CS8625;CS8629;CS8633;CS8524;CS8509;CS8524;CS8767</WarningsAsErrors>

Delectable answered 21/2, 2020 at 12:40 Comment(2)
Regarding your update: maybe CS8618 C# Non-nullable property is uninitialized. Consider declaring the property as nullable. might also be relevant to include.Aristippus
@Aristippus this is what we are trying to avoid for all DTOs, models and other classes which will never be created with new()Delectable
C
7

The problem was that the .editorconfig file was overriding the Visual Studio setting to treat all warnings as errors with many lines like:

dotnet_diagnostic.CS8602.severity = warning

This forces CS8602 to be a warning.

How this happened: In a previous attempt at turning all nullable reference warnings into errors, I set many of them as errors in the editor config. In that, I discovered both that there were a ton of different warning numbers and that my codebase wasn't ready for them to be errors throughout the entire solution. So I set them to "warning" in the editor config because I didn't want to lose the list of warnings I had found. Then later, having forgotten all about that, I decided to turn on treat warnings as errors on a project by project basis.

Calculous answered 3/10, 2019 at 6:23 Comment(0)
B
1

Since Google is pointing to this question when one asks for <WarningsAsErrors>Nullable</WarningsAsErrors>, I would like to point out that if you googling why it isn't working (produce build errors) and you inject this by Directory.Build.props, it won't work by design.

The property gets injected from the Directory.Build.props, but gets overridden by the CSProj default (no error on build).

The approach with Directory.Build.targets removes a possibility to override this from CSProj completely.

More granular approach would be probably by using the root .editorconfig and list the behavior explicitly with possible local override.

Beatific answered 1/7, 2023 at 4:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.