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
Copy file name to clipboardExpand all lines: standard/patterns.md
+158-3Lines changed: 158 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
## 11.1 General
4
4
5
-
A ***pattern*** is a syntactic form that can be used with the `is` operator ([§12.14.12](expressions.md#121412-the-is-operator)), in a *switch_statement* ([§13.8.3](statements.md#1383-the-switch-statement)), and in a *switch_expression* ([§12.11](expressions.md#1211-switch-expression)) to express the shape of data against which incoming data is to be compared. Patterns may be recursive, so that parts of the data may be matched against ***sub-patterns***.
5
+
A ***pattern*** is a syntactic form that can be used with the `is` operator ([§12.14.12](expressions.md#121412-the-is-operator)), in a *switch_statement* ([§13.8.3](statements.md#1383-the-switch-statement)), and in a *switch_expression* ([§12.11](expressions.md#1211-switch-expression)) to express the shape of data against which incoming data is to be compared. Patterns may be recursive, so that parts of the data may be matched against ***sub-patterns***.
6
6
7
7
A pattern is tested against a value in a number of contexts:
8
8
@@ -11,7 +11,7 @@ A pattern is tested against a value in a number of contexts:
11
11
- In a switch expression, the *pattern* of a *switch_expression_arm* is tested against the expression on the switch-expression’s left-hand-side.
12
12
- In nested contexts, the *sub-pattern* is tested against values retrieved from properties, fields, or indexed from other input values, depending on the pattern form.
13
13
14
-
The value against which a pattern is tested is called the ***pattern input value***.
14
+
The value against which a pattern is tested is called the ***pattern input value***. Patterns may be combined using Boolean logic.
15
15
16
16
## 11.2 Pattern forms
17
17
@@ -21,12 +21,16 @@ A pattern may have one of the following forms:
21
21
22
22
```ANTLR
23
23
pattern
24
-
: declaration_pattern
24
+
: '(' pattern ')'
25
+
| declaration_pattern
25
26
| constant_pattern
26
27
| var_pattern
27
28
| positional_pattern
28
29
| property_pattern
29
30
| discard_pattern
31
+
| type_pattern
32
+
| relational_pattern
33
+
| logical_pattern
30
34
;
31
35
```
32
36
@@ -406,6 +410,157 @@ It is a compile-time error to use a discard pattern in a *relational_expression*
A *type_pattern* isusedtotestthatthepatterninputvalue ([§11.1](patterns.md#111-general)) hasagiventype.
416
+
417
+
```ANTLR
418
+
type_pattern
419
+
:type
420
+
;
421
+
```
422
+
423
+
The runtime type of the value is tested against *type* using the same rules specified in the is-type operator ([§12.12.12.1](expressions.md#1212121-the-is-type-operator)). If the test succeeds, the pattern matches that value. It is a compile-time error if the *type* is a nullable type. This pattern form never matches a `null` value.
A *relational_pattern* is used to relationally test the pattern input value ([§11.1](patterns.md#111-general)) against a constant value.
428
+
429
+
```ANTLR
430
+
relational_pattern
431
+
: '<' constant_expression
432
+
| '<=' constant_expression
433
+
| '>' constant_expression
434
+
| '>=' constant_expression
435
+
;
436
+
```
437
+
438
+
Relational patterns support the relational operators `<`, `<=`, `>`, and `>=` on all of the built-in types that support such binary relational operators with both operands having the same type: `sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `char`, `float`, `double`, `decimal`, `nint`, `nuint`, and enums.
439
+
440
+
It is a compile-time error if `constant_expression`is `double.NaN`, `float.NaN`, or `null_literal`.
441
+
442
+
When the input value has a type for which a suitable built-in binary relational operator is defined, the evaluation of that operator is taken as the meaning of the relational pattern. Otherwise, the input value is converted to the type of `constant_expression` using an explicit nullable or unboxing conversion. It is a compile-time error if no such conversion exists. The pattern is considered to not match if the conversion fails. If the conversion succeeds, the result of the pattern-matching operation is the result of evaluating the expression `e «op» v` where `e` is the converted input, «op» is the relational operator, and `v` is the `constant_expression`.
A *logical_pattern* isusedtonegateapatterninputvalue ([§11.1](patterns.md#111-general)) ortocombinethatvaluewithapatternusingaBooleanoperator.
474
+
475
+
```ANTLR
476
+
logical_pattern
477
+
: disjunctive_pattern
478
+
;
479
+
480
+
disjunctive_pattern
481
+
:disjunctive_pattern'or'conjunctive_pattern
482
+
|conjunctive_pattern
483
+
;
484
+
485
+
conjunctive_pattern
486
+
:conjunctive_pattern'and'negated_pattern
487
+
|negated_pattern
488
+
;
489
+
490
+
negated_pattern
491
+
:'not'negated_pattern
492
+
|pattern
493
+
;
494
+
```
495
+
496
+
`not`, `and`, and `or` are collectively called ***pattern operators***.
497
+
498
+
A *negated_pattern* matches if the pattern being negated does not match, and vice versa. A *conjunctive_pattern* requires both patterns to match. A *disjunctive_pattern* requires either pattern to match. Unlike their language operator counterparts, `&&` and `||`, `and` and `or` are *not* short-circuiting operators.
499
+
500
+
> *Note*: As indicated by the grammar, `not` has precedence over `and`, which has precedence over `or`. This can be explicitly indicated or overridden by using parentheses. *end note*
501
+
502
+
When a *pattern* is used with `is`, any pattern operators in that *pattern* have higher precedence than their logical operator counterparts. Otherwise, those pattern operators have lower precedence.
0 commit comments