loading...

.NET Core 3.0 Preview w/ C# 8.0 Nullable Reference Types

jeikabu profile image jeikabu Originally published at rendered-obsolete.github.io on ・3 min read

Awoke this morning and saw the .NET Core 3.0 Preview announcement.

Download available from github releases.

C# 8.0

Run dotnet --list-sdks:

1.1.11 [/usr/local/share/dotnet/sdk]
2.0.0 [/usr/local/share/dotnet/sdk]
2.1.4 [/usr/local/share/dotnet/sdk]
2.1.301 [/usr/local/share/dotnet/sdk]
2.1.302 [/usr/local/share/dotnet/sdk]
3.0.100-preview-009812 [/usr/local/share/dotnet/sdk]

To use C# 8, in a project file:

<PropertyGroup>
    <LangVersion>8.0</LangVersion>
</PropertyGroup>

dotnet build:

/usr/local/share/dotnet/sdk/3.0.100-preview-009812/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(220,5): error MSB4018: The "ResolvePackageAssets" task failed unexpectedly. [/XXX/zxy/tests/tests.csproj]
/usr/local/share/dotnet/sdk/3.0.100-preview-009812/Sdks/Microsoft.NET.Sdk/targets/Microsoft.PackageDependencyResolution.targets(220,5): error MSB4018: System.IO.InvalidDataException: Found invalid data while decoding. [/XXX/zxy/tests/tests.csproj]

dotnet clean followed by another dotnet build fixed this.

dotnet test and everything seems good so far.

Nullable Reference Types

The feature I’ve been most interested in is “nullable reference types”, a compile-time check to avoid dereferencing null at run-time. I’ve been using the Nullable Reference Types Preview, and the idea is the compiler generates warnings and you choose to ignore them (tsk tsk) or turn them into errors:

<PropertyGroup>
    <MSBuildTreatWarningsAsErrors>true</MSBuildTreatWarningsAsErrors>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

In the first preview the warnings were on by default, but according to that wiki you now need to opt-in with [module: System.Runtime.CompilerServices.NonNullTypes] in each project. Added that to a project and fail:

Program.cs(8,10): error CS8636: Explicit application of 'System.Runtime.CompilerServices.NonNullTypesAttribute' is not allowed. [/XXX/zxy/zxy0/zxy0.csproj]

Opened up that assembly and it doesn’t even contain NonNullTypesAttribute. Luckily, open-source comes to the rescue because this issue shows what changed:

#nullable enable
namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            string test = null; // line 8
            System.Console.WriteLine(test.Length);
        }
    }
}

dotnet build:

Program.cs(10,27): error CS8600: Converting null literal or possible null value to non-nullable type. [/XXX/junk/junk.csproj]
Program.cs(11,31): error CS8602: Possible dereference of a null reference. [/XXX/junk/junk.csproj]

No assigning null to a type that shouldn’t be null. Nice. Change line 8 to:

string? test = null;

And it still fails with:

Program.cs(9,38): error CS8602: Possible dereference of a null reference. [/Users/jake/projects/junk/junk.csproj]

string? might be null, but add a check and it compiles:

string? test = null;
if (test != null)
    System.Console.WriteLine(test.Length);

Unfortunately, this is a compiler heuristic/lint instead of a gurantee provided by the type system like option in F#, Rust, etc. The compiler doesn’t fail this:

static string test = null;
static void Main(string[] args)
{
    System.Console.WriteLine(test.Length);
}

Hopefully they’ll keep making improvements.

Visual Studio

To try this out in VS you need the Visual Studio 2019 Preview.

Right-click a project and select Properties > Build and:

  • In Treat warnings as errors select All
  • Click Advanced… and for Language Version select C# 8.0 (beta).

Posted on by:

Discussion

markdown guide
 

According to this SO
It can be enabled in .csproj file:

<PropertyGroup>
  ...
  <NullableReferenceTypes>true</NullableReferenceTypes>
  <LangVersion>8.0</LangVersion>
</PropertyGroup>
 

Nice find!

Looks like I wasn't the only person that had trouble enabling this. From GitHub issues (including the one linked on SO) it looks like nullable types isn't quite ready in Preview 1.

Thanks for the update!