Fix small spec bugs regarding nullable reference type parameters#1389
Fix small spec bugs regarding nullable reference type parameters#1389
Conversation
62bd6f5 to
a4af924
Compare
| ### 8.2.1 General | ||
|
|
||
| A reference type is a class type, an interface type, an array type, a delegate type, or the `dynamic` type. For each non-nullable reference type, there is a corresponding nullable reference type noted by appending the `?` to the type name. | ||
| A reference type is a class type, an interface type, an array type, a delegate type, the `dynamic` type, or any type parameter that is constrained to be a reference type (that is, any type parameter with the reference type constraint or a class type constraint ([§15.2.5](classes.md#1525-type-parameter-constraints))). For each non-nullable reference type, there is a corresponding nullable reference type noted by appending the `?` to the type name. |
There was a problem hiding this comment.
This borrows the existing language which appears in https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/types.md#8312-nullable-value-types:
Conversely, a non-nullable value type is any value type other than
System.Nullable<T>and its shorthandT?(for anyT), plus any type parameter that is constrained to be a non-nullable value type (that is, any type parameter with a value type constraint (§15.2.5)).
| > *Note*: To specify that a type argument is a nullable reference type, don’t add the nullable type annotation as a constraint (use `T : class` or `T : BaseClass`), but use `T?` throughout the generic declaration to indicate the corresponding nullable reference type for the type argument. *end note* | ||
|
|
||
| <!-- Remove in C# 9, when this is allowed --> | ||
| The nullable type annotation, `?`, can’t be used on an unconstrained type argument. |
There was a problem hiding this comment.
Here is an example of a type parameter that is not unconstrained, and thus was not disallowed by the original statement, which is still not allowed to use ?:
#nullable enable
class C
{
void M<T>(T? test) where T : System.IDisposable
{
}
}Roslyn:
A nullable type parameter must be known to be a value type or non-nullable reference type unless language version '9.0' or greater is used. Consider changing the language version or adding a 'class', 'struct', or type constraint.
a4af924 to
2b23085
Compare
| <!-- Add in C# 9, when `?` is allowed on nullable reference type parameters. --> | ||
| <!-- For a type parameter `T` when the type argument is a nullable reference type `C?`, instances of `T?` are interpreted as `C?`, not `C??`. --> |
There was a problem hiding this comment.
Instances of T? do not exist when the type argument is a nullable reference type C? in C# 8, e.g.:
#nullable enable
class C
{
void M<T>(T? test) where T : class?
{
}
}Roslyn:
A nullable type parameter must be known to be a value type or non-nullable reference type unless language version '9.0' or greater is used. Consider changing the language version or adding a 'class', 'struct', or type constraint.
fa3774f to
918e022
Compare
BillWagner
left a comment
There was a problem hiding this comment.
These all look good to me.
I'd like to have another set of eyes on them before merging, or have brief review in our next meeting.
/cc @jskeet
|
Oops! Missed bringing this to the meeting since @jskeet didn't have a chance to look at it. I'll add the tag now. |
While working on #1386, I found some spec bugs I could fix.