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);
        }
    }
}

Update:

Per this SO, can be enabled for an entire project via:

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

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