tabs ↹ over ␣ ␣ ␣ spaces

by Jiří {x2} Činčura

Switch to errors instead of warnings for nullable reference types in C# 8

21 Jan 2019 2 mins C#, MSBuild, Roslyn

Nullable reference types coming in C# 8 are a great addition to anyone’s toolbox. But if you tried it you probably know “just” warnings are produced. And sometimes you’d like to have errors instead of warnings, so the build fails hard or something like that. It’s surprisingly easy to do so.

You might have heard about the TreatWarningsAsErrors option, which basically promotes all warnings to errors (which is sometimes useful). But there’s also WarningsAsErrors option which is a list of warnings to be treated as errors (and that is subsequently passed to csc). With that we’re half way there.

Sadly, there isn’t only one warning for nullable references types, but because Roslyn is open source, we don’t have to guess. In ErrorCode.cs we can see all and also guess from the name what’s the issue covered.

When you’re done selecting the ones you’re interested in, just add WarningsAsErrors tag into your csproj (or you can do it via UI in Properties of the project). Following is how a very simple project file with some warnings added might look like.

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

Why I selected these three, you ask? Just a few – common in my opinion – to try and show here.

Probably the most famous will be CS8602 which is Possible dereference of a null reference..

static void Foo(string? s)
{
    var x = s.Length;
}

Another could be CS8603 which is Possible null reference return..

static string Bar(DateTime? d)
{
    return d?.ToString();
}

The last one is CS8600 Converting null literal or possible null value to non-nullable type. (I like how it also takes into account the null literal).

static void Baz()
{
    string? F() => null;
    string f = F();
}

The list of error codes on the link above contains all and one can surely include all. But it’s also about understading and resolving the warnings/errors properly, not just making them dissappear with !s or ?s.

Follow-up post.

Profile Picture Jiří Činčura is .NET, C# and Firebird expert. He focuses on data and business layers, language constructs, parallelism, databases and performance. For almost two decades he contributes to open-source, i.e. FirebirdClient. He works as a senior software engineer for Microsoft. Frequent speaker and blogger at www.tabsoverspaces.com.