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
* Add more details on pattern binding
Fixes#43177
We've had feedback that indicates confusion on how C# parses patterns with multiple `and`, `not`, and `or` patterns. Add more examples that demonstrates the problems. Explain the binding order, and recommend using parentheses when the pattern can be misinterpreted.
Also, do a grammar check.
* build error
* Apply suggestions from code review
Co-authored-by: Genevieve Warren <[email protected]>
* grammar
---------
Co-authored-by: Genevieve Warren <[email protected]>
Copy file name to clipboardExpand all lines: docs/csharp/language-reference/operators/patterns.md
+23-13Lines changed: 23 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
---
2
2
title: "Patterns - Pattern matching using the is and switch expressions."
3
3
description: "Learn about the patterns supported by the `is` and `switch` expressions. Combine multiple patterns using the `and`, `or`, and `not` operators."
4
-
ms.date: 01/30/2023
4
+
ms.date: 11/14/2024
5
5
f1_keywords:
6
6
- "and_CSharpKeyword"
7
7
- "or_CSharpKeyword"
@@ -12,9 +12,9 @@ helpviewer_keywords:
12
12
- "or keyword [C#]"
13
13
- "not keyword [C#]"
14
14
---
15
-
# Pattern matching - the `is` and `switch` expressions, and operators `and`, `or` and `not` in patterns
15
+
# Pattern matching - the `is` and `switch` expressions, and operators `and`, `or`, and `not` in patterns
16
16
17
-
You use the [`is` expression](is.md), the [switch statement](../statements/selection-statements.md#the-switch-statement) and the [switch expression](switch-expression.md) to match an input expression against any number of characteristics. C# supports multiple patterns, including declaration, type, constant, relational, property, list, var, and discard. Patterns can be combined using Boolean logic keywords `and`, `or`, and `not`.
17
+
You use the [`is` expression](is.md), the [switch statement](../statements/selection-statements.md#the-switch-statement), and the [switch expression](switch-expression.md) to match an input expression against any number of characteristics. C# supports multiple patterns, including declaration, type, constant, relational, property, list, var, and discard. Patterns can be combined using Boolean logic keywords `and`, `or`, and `not`.
18
18
19
19
The following C# expressions and statements support pattern matching:
20
20
@@ -26,14 +26,14 @@ In those constructs, you can match an input expression against any of the follow
26
26
27
27
-[Declaration pattern](#declaration-and-type-patterns): to check the run-time type of an expression and, if a match succeeds, assign an expression result to a declared variable.
28
28
-[Type pattern](#declaration-and-type-patterns): to check the run-time type of an expression.
29
-
-[Constant pattern](#constant-pattern): to test if an expression result equals a specified constant.
29
+
-[Constant pattern](#constant-pattern): to test that an expression result equals a specified constant.
30
30
-[Relational patterns](#relational-patterns): to compare an expression result with a specified constant.
31
-
-[Logical patterns](#logical-patterns): to test if an expression matches a logical combination of patterns.
32
-
-[Property pattern](#property-pattern): to test if an expression's properties or fields match nested patterns.
31
+
-[Logical patterns](#logical-patterns): to test that an expression matches a logical combination of patterns.
32
+
-[Property pattern](#property-pattern): to test that an expression's properties or fields match nested patterns.
33
33
-[Positional pattern](#positional-pattern): to deconstruct an expression result and test if the resulting values match nested patterns.
34
34
-[`var` pattern](#var-pattern): to match any expression and assign its result to a declared variable.
35
35
-[Discard pattern](#discard-pattern): to match any expression.
36
-
-[List patterns](#list-patterns): to test if sequence elements match corresponding nested patterns. Introduced in C# 11.
36
+
-[List patterns](#list-patterns): to test that a sequence of elements matches corresponding nested patterns. Introduced in C# 11.
37
37
38
38
[Logical](#logical-patterns), [property](#property-pattern), [positional](#positional-pattern), and [list](#list-patterns) patterns are *recursive* patterns. That is, they can contain *nested* patterns.
39
39
@@ -71,7 +71,7 @@ For that purpose you can use a *type pattern*, as the following example shows:
Like a declaration pattern, a type pattern matches an expression when an expression result is non-null and its run-time type satisfies any of the conditions listed above.
74
+
Like a declaration pattern, a type pattern matches an expression when an expression result is non-null and its run-time type satisfies any of the preceding conditions.
75
75
76
76
To check for non-null, you can use a [negated](#logical-patterns)`null`[constant pattern](#constant-pattern), as the following example shows:
77
77
@@ -145,20 +145,30 @@ As the preceding example shows, you can repeatedly use the pattern combinators i
145
145
146
146
### Precedence and order of checking
147
147
148
-
The pattern combinators are ordered from the highest precedence to the lowest as follows:
148
+
The pattern combinators are ordered based on the binding order of expressions as follows:
149
149
150
150
-`not`
151
151
-`and`
152
152
-`or`
153
153
154
-
When a logical pattern is a pattern of an `is` expression, the precedence of logical pattern combinators is **higher** than the precedence of logical operators (both [bitwise logical](bitwise-and-shift-operators.md)and[Boolean logical](boolean-logical-operators.md) operators). Otherwise, the precedence of logical pattern combinators is **lower** than the precedence of logical and conditional logical operators. For the complete list of C# operators ordered by precedence level, see the [Operator precedence](index.md#operator-precedence) section of the [C# operators](index.md) article.
154
+
The `not`pattern binds to its operand first. The `and` pattern binds after any `not` pattern expression binding. The `or` pattern binds after all `not`and`and` patterns are bound to operands. The following example tries to match all characters that aren't lower case letters, `a` - `z`. It has an error, because the `not` pattern binds before the `and` pattern:
155
155
156
-
To explicitly specify the precedence, use parentheses, as the following example shows:
Adding parentheses becomes more important as your patterns become more complicated. In general, use parentheses to clarify your patterns for other developers, as the following example shows:
> The order in which patterns are checked is undefined. At run time, the right-hand nested patterns of `or` and `and` patterns can be checked first.
171
+
> The order in which patterns having the same binding order are checked is undefined. At run time, the right-hand nested patterns of multiple `or`patterns and multiple`and` patterns can be checked first.
162
172
163
173
For more information, see the [Pattern combinators](~/_csharplang/proposals/csharp-9.0/patterns3.md#pattern-combinators) section of the feature proposal note.
164
174
@@ -270,7 +280,7 @@ Beginning with C# 11, you can match an array or a list against a *sequence* of p
As the preceding example shows, a list pattern is matched when each nested pattern is matched by the corresponding element of an input sequence. You can use any pattern within a list pattern. To match any element, use the [discard pattern](#discard-pattern) or, if you also want to capture the element, the [var pattern](#var-pattern), as the following example shows:
283
+
As the preceding example shows, a list pattern is matched when each nested pattern matches the corresponding element of an input sequence. You can use any pattern within a list pattern. To match any element, use the [discard pattern](#discard-pattern) or, if you also want to capture the element, the [var pattern](#var-pattern), as the following example shows:
0 commit comments