Skip to content

Add notnull example #1309

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 16, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion standard/classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,40 @@ For a type parameter `T` when the type argument is a nullable reference type `C?

The ***not null*** constraint specifies that a type argument used for the type parameter should be a non-nullable value type or a non-nullable reference type. A type argument that isn’t a non-nullable value type or a non-nullable reference type is allowed, but a compiler may produce a diagnostic warning.

Because `notnull` is not a keyword, in *primary_constraint* the not null constraint is always syntactically ambiguous with *class_type*. For compatibility reasons, if a name lookup ([§12.8.4](expressions.md#1284-simple-names)) of the name `notnull` succeeds it is treated as a `class_type`. Otherwise it is treated as the not null constraint.
Because `notnull` is not a keyword, in *primary_constraint* the not null constraint is always syntactically ambiguous with *class_type*. For compatibility reasons, if a name lookup ([§12.8.4](expressions.md#1284-simple-names)) of the name `notnull` succeeds it shall be treated as a `class_type`. Otherwise it shall be treated as the not null constraint.

> *Example*: The following class demonstrates the use of various type arguments against different constraints, indicating warnings which may be issued by a compiler.
>
> <!-- Example: {template:"standalone-lib-without-using", name:"TypeParameterConstraints0", expectedWarnings:["CS8714","CS8714","CS8631"], ignoredWarnings:["CS0168"]} -->
> ```csharp
> #nullable enable
> public class C { }
> public class A<T> where T : notnull { }
> public class B1<T> where T : C { }
> public class B2<T> where T : C? { }
> class Test
> {
> static void M()
> {
> // nonnull constraint allows nonnullable struct type argument
> A<int> x1;
> // possible warning: nonnull constraint prohibits nullable struct type argument
> A<int?> x2;
> // nonnull constraint allows nonnullable class type argument
> A<C> x3;
> // possible warning: nonnull constraint prohibits nullable class type argument
> A<C?> x4;
> // nonnullable base class requirement allows nonnullable class type argument
> B1<C> x5;
> // possible warning: nonnullable base class requirement prohibits nullable class type argument
> B1<C?> x6;
> // nullable base class requirement allows nonnullable class type argument
> B2<C> x7;
> // nullable base class requirement allows nullable class type argument
> B2<C?> x8;
> }
> }
> ```

The value type constraint specifies that a type argument used for the type parameter shall be a non-nullable value type. All non-nullable struct types, enum types, and type parameters having the value type constraint satisfy this constraint. Note that although classified as a value type, a nullable value type ([§8.3.12](types.md#8312-nullable-value-types)) does not satisfy the value type constraint. A type parameter having the value type constraint shall not also have the *constructor_constraint*, although it may be used as a type argument for another type parameter with a *constructor_constraint*.

Expand Down