DEV Community

jeikabu
jeikabu

Posted on • Originally published at rendered-obsolete.github.io on

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

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]
Enter fullscreen mode Exit fullscreen mode

To use C# 8, in a project file:

<PropertyGroup>
    <LangVersion>8.0</LangVersion>
</PropertyGroup>
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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

string? test = null;
Enter fullscreen mode Exit fullscreen mode

And it still fails with:

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

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

string? test = null;
if (test != null)
    System.Console.WriteLine(test.Length);
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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).

Top comments (2)

Collapse
 
dthpth profile image
Sergey Vershinin

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

<PropertyGroup>
  ...
  <NullableReferenceTypes>true</NullableReferenceTypes>
  <LangVersion>8.0</LangVersion>
</PropertyGroup>
Collapse
 
jeikabu profile image
jeikabu • Edited

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!