0

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??

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
Mr. Boy
  • 60,845
  • 93
  • 320
  • 589

1 Answers1

3

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

}
Guru Stron
  • 102,774
  • 10
  • 95
  • 132
  • I'm not sure I understand your second example `notNull0` but thanks this is clear - missed that detail. Thanks. – Mr. Boy Sep 07 '22 at 13:20
  • 1
    @Mr.Boy was glad to help! `is {}` checks that object [is not null](https://stackoverflow.com/a/62140081/2501279) and creates alias variable for the checked. It is not required in general case but AFAIK one time I got some corner case when compiler needed it. – Guru Stron Sep 07 '22 at 13:32