Sergey Slepov
Sergey Slepov

Reputation: 2121

Is the information about C# 8 nullable reference types stored in a .NET assembly?

Will consumers of a Nuget package written in C# 8 with nullable reference types see the information about nullability of fields / parameters defined in that package? Will the C# 8 compiler be able to use that information to issue appropriate warnings?

Upvotes: 4

Views: 1016

Answers (1)

Panagiotis Kanavos
Panagiotis Kanavos

Reputation: 131706

Yes, provided they also use C# 8 or later and have Nullable enabled. This already happens with the BCL types.

NRTs in C# 8 don't introduce a new kind of type. The compiler generates NullableContext and Nullable attributes in projects or files where NRTs are enabled. These are used to analyze the code and issue nullability warnings. Whether nullability is enabled or not, a string and a string? are still the same type, a string.

Jon Skeet's NullableAttribute And C# 8 explains how those attributes work and how they affect the public API of a package, in this case Noda Time. The package was ported to C# 8 back in February 2019.

As Jon Skeet explains:

The C# 8 compiler creates an internal NullableAttribute class within the assembly (which I assume it wouldn’t if we were targeting a framework that already includes such an attribute) and applies the attribute anywhere it’s relevant.

This makes the change transparent to older C# compilers

Check this Sharplab.io example. The following simple class:

#nullable enable
using System;
public class C {
    public void M(C c) {
    }
}

Generates this intermediate C# code:

public class C
{
    [System.Runtime.CompilerServices.NullableContext(1)]
    public void M(C c)
    {
    }
}

While this :

    public C M(C? c) {
        return c ?? throw new ArgumentNullException(nameof(c));
    }

Generates this intermediate C# :

    [System.Runtime.CompilerServices.NullableContext(1)]
    public C M([System.Runtime.CompilerServices.Nullable(2)] C c)
    {
        if (c != null)
        {
            return c;
        }
        throw new ArgumentNullException("c");
    }
}

Upvotes: 5

Related Questions