You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Update classes.md
* Tweak the recently added description of unmanaged constraint
Describe what happens when a type called `unmanaged` exists in the scope of an unmanaged constraint.
* Update standard/classes.md
* Update standard/classes.md
* Update standard/classes.md
* Apply suggestions from code review
Co-authored-by: Nigel-Ecma <[email protected]>
Co-authored-by: Jon Skeet <[email protected]>
* Apply suggestions from code review
* Update foreword.md
Remove V6-specific entries, and add first new V7 items.
* add unmanaged to list of contextual keywords
---------
Co-authored-by: Bill Wagner <[email protected]>
Co-authored-by: Nigel-Ecma <[email protected]>
Co-authored-by: Jon Skeet <[email protected]>
Copy file name to clipboardExpand all lines: standard/classes.md
+12-3Lines changed: 12 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -415,6 +415,7 @@ primary_constraint
415
415
:class_type
416
416
|'class'
417
417
|'struct'
418
+
|'unmanaged'
418
419
;
419
420
420
421
secondary_constraints
@@ -433,21 +434,29 @@ Each *type_parameter_constraints_clause* consists of the token `where`, followed
433
434
434
435
The list of constraints given in a `where` clause can include any of the following components, in this order: a single primary constraint, one or more secondary constraints, and the constructor constraint, `new()`.
435
436
436
-
A primary constraint can be a class type or the ***reference type constraint***`class` or the ***value type constraint***`struct`. A secondary constraint can be a *type_parameter* or *interface_type*.
437
+
A primary constraint can be a class type, the ***reference type constraint***`class`, the ***value type constraint***`struct`, or the ***unmanaged type constraint***`unmanaged`.
438
+
439
+
A secondary constraint can be a *type_parameter* or *interface_type*.
437
440
438
441
The reference type constraint specifies that a type argument used for the type parameter shall be a reference type. All class types, interface types, delegate types, array types, and type parameters known to be a reference type (as defined below) satisfy this constraint.
439
442
440
443
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.11](types.md#8311-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*.
441
444
442
445
> *Note*: The `System.Nullable<T>` type specifies the non-nullable value type constraint for `T`. Thus, recursively constructed types of the forms `T??` and `Nullable<Nullable<T>>` are prohibited. *end note*
443
446
447
+
Because `unmanaged` is not a keyword, in *primary_constraint* the unmanaged constraint is always syntactically ambiguous with *class_type*. For compatibility reasons, if a name lookup (§11.7.4) of the name `unmanaged` succeeds it is treated as a `class_type`. Otherwise it is treated as the unmanaged constraint.
448
+
449
+
The unmanaged type constraint specifies that a type argument used for the type parameter shall be a non-nullable unmanaged type ([§8.8](types.md#88-unmanaged-types)).
450
+
451
+
Pointer types are never allowed to be type arguments, and don't satisfy any type constraints, even unmanaged, despite being unmanaged types.
452
+
444
453
If a constraint is a class type, an interface type, or a type parameter, that type specifies a minimal “base type” that every type argument used for that type parameter shall support. Whenever a constructed type or generic method is used, the type argument is checked against the constraints on the type parameter at compile-time. The type argument supplied shall satisfy the conditions described in [§8.4.5](types.md#845-satisfying-constraints).
445
454
446
455
A *class_type* constraint shall satisfy the following rules:
447
456
448
457
- The type shall be a class type.
449
458
- The type shall not be `sealed`.
450
-
- The type shall not be one of the following types: `System.Array`, `System.Delegate`, `System.Enum`, or `System.ValueType`.
459
+
- The type shall not be one of the following types: `System.Array` or `System.ValueType`.
451
460
- The type shall not be `object`.
452
461
- At most one constraint for a given type parameter may be a class type.
453
462
@@ -483,7 +492,7 @@ It is valid for `S` to have the value type constraint and `T` to have the refer
483
492
484
493
If the `where` clause for a type parameter includes a constructor constraint (which has the form `new()`), it is possible to use the `new` operator to create instances of the type ([§11.7.15.2](expressions.md#117152-object-creation-expressions)). Any type argument used for a type parameter with a constructor constraint shall be a value type, a non-abstract class having a public parameterless constructor, or a type parameter having the value type constraint or constructor constraint.
485
494
486
-
It is a compile-time error for *type_parameter_constraints* having a *primary_constraint* of `struct` to also have a *constructor_constraint*.
495
+
It is a compile-time error for *type_parameter_constraints* having a *primary_constraint* of `struct`or `unmanaged`to also have a *constructor_constraint*.
487
496
488
497
> *Example*: The following are examples of constraints:
0 commit comments