T?, nullable type parameter in C# 9

Viewed 1182

This program has two errors:

using System;

T? f<T>(T? t)
{    
    t = null; //  Error CS0403  Cannot convert null to type parameter 'T' because it could be a non-nullable value type
    return default(T?);
}

if(f(10) is null) // Error  CS0037  Cannot convert null to 'int' because it is a non-nullable value type    
    Console.WriteLine("null");

T? has to be a nullable type. But it seems T? is the same as T in the above program.

Is ? ignored in T??


Edit: Both errors disappear with a struct constraint:

using System;

T? f<T>(T? t)  where T : struct
{    
    t = null; // error
    return default(T?);
}

if(f<int>(10) is null) // error
    Console.WriteLine("null");

I don't understand why the constraint changes the results.

2 Answers

When you say T? in T? and in (T? t), they both refer to nullable reference types, not to the special Nullable<T> struct. There's no way that you can specify a generic parameter such that you can treat it as a class and a nullable value type.

The second error is just because f(10) (so f<int>(10)) is implicitly taken as an int (as there's no such thing as a nullable reference int value), so null isn't valid, just as if you did if (10 is null).


If T stops being open and instead you add a constraint such as where T : struct, T? becomes System.Nullable<T> rather than a nullable reference parameter, and so the code becomes the exact same as before nullable reference types were introduced.

I don't have an idea for the first error, but the second.

f(10) is null is inferred as int in lieu of int? since 10 is of int type. Either f((int?)10) is null, or f<int?>(10) is null should be used.

Related