Search code examples
c#nullable-reference-typesc#-10.0

Are nullable reference types not Nullable<T>?


I created a new C#10/.net6 library project in VS2022 using the standard template, NRTs are enabled by default (nullable : enabled). I notice that nullable reference types do not appear to support Nullable properties Value and HasValue

MRE (using #nullable annotation explicitly)

using System;
                    
public class Program
{
    public static void Main()
    {
#nullable enable
        object? o =null;
        if(o.HasValue)
        {}
        Console.WriteLine("Hello World");
    }
}

'object' does not contain a definition for 'HasValue' and no accessible extension method 'HasValue' accepting a first argument of type 'object' could be found

Are nullable reference types not actually Nullable<T>? o is declared as object? so why does the compiler refer to object rather than object??


Solution

  • No, they are not. From the docs:

    However, nullable reference types and nullable value types are implemented differently: nullable value types are implemented using System.Nullable<T>, and nullable reference types are implemented by attributes read by the compiler. For example, string? and string are both represented by the same type: System.String. However, int? and int are represented by System.Nullable<System.Int32> and System.Int32, respectively.

    Basically NRT is just compile time information (though you can get access it in runtime via reflection like done here).

    As for the case - just use ordinary null check and that's it.

    if(o != null)
    {
    
    }
    

    or pattern matching:

    if(o is {} notNullO)
    {
    
    }