In this code, the type of new Of<int>().Value
is int
, not int?
even though the field declaration for Value
has a ?
Does the C# spec clarify that in this case the type of T?
will be a (not-nullable) Value type and not a Nullable Value type? I can't find it.
#nullable enable
void Main()
{
Console.WriteLine( new Of<int>().Value.GetType() );
}
class Of<T>
{
public T? Value;
public Of(T? value) => Value = value;
public Of() {}
public Of<T> Create() => new Of<T>(default);
}
The C# spec has not been properly updated for many of the new features. There are separate addendums for these.
Unconstrained type parameters with regards NRT is in the feature spec:
In C#9,
?
annotations can be applied to any type parameter, regardless of constraints.Unless a type parameter is explicitly constrained to value types, annotations can only be applied within a
#nullable enable
context.If a type parameter
T
is substituted with a reference type, thenT?
represents a nullable instance of that reference type.var s1 = new string[0].FirstOrDefault(); // string? s1 var s2 = new string?[0].FirstOrDefault(); // string? s2
If
T
is substituted with a value type, thenT?
represents an instance ofT
. (my bold)var i1 = new int[0].FirstOrDefault(); // int i1 var i2 = new int?[0].FirstOrDefault(); // int? i2
If
T
is substituted with an annotated typeU?
, thenT?
represents the annotated typeU?
rather thanU??
.var u1 = new U[0].FirstOrDefault(); // U? u1 var u2 = new U?[0].FirstOrDefault(); // U? u2
If
T
is substituted with a typeU
, thenT?
representsU?
, even within a#nullable disable
context.#nullable disable var u3 = new U[0].FirstOrDefault(); // U? u3