11.1 일반
패턴은 연산자(is), switch_statement(§13.8.3), switch_expression(§12.12)에서 들어오는 데이터를 비교할 데이터의 모양을 표현하는 데 사용할 수 있는 구문 형식입니다. 패턴은 재귀적일 수 있으므로 데이터의 일부가 하위 패턴과 일치할 수 있습니다.
패턴은 여러 컨텍스트의 값에 대해 테스트됩니다.
- switch 문에서 사례 레이블의 패턴 은 switch 문의 식 에 대해 테스트됩니다.
- is-pattern 연산자에서 오른쪽의 패턴은 왼쪽의 식에 대해 테스트됩니다.
- switch 식에서 switch_expression_arm패턴은 switch 식의 왼쪽에 있는 식에 대해 테스트됩니다.
- 중첩 컨텍스트에서 하위 패턴 은 패턴 폼에 따라 속성, 필드 또는 다른 입력 값에서 인덱싱된 값에 대해 테스트됩니다.
패턴이 테스트되는 값을 패턴 입력 값이라고 부릅니다.
11.2 패턴 양식
11.2.1 일반
패턴에는 다음 형식 중 하나가 있을 수 있습니다.
pattern
: logical_pattern
;
primary_pattern
: parenthesized_pattern
| declaration_pattern
| constant_pattern
| var_pattern
| positional_pattern
| property_pattern
| discard_pattern
| type_pattern
| relational_pattern
;
parenthesized_pattern
: '(' pattern ')'
;
이 '(' pattern ')' 프로덕션에서는 패턴을 괄호로 묶어 logical_pattern중 하나를 사용하여 결합된 패턴 간에 평가 순서를 적용할 수 있습니다.
일부 패턴은 지역 변수의 선언을 초래할 수 있습니다.
각 패턴 양식은 패턴이 적용될 수 있는 입력 값에 대한 형식 집합을 정의합니다. 패턴 P 이 일치할이 적용됩니다. 적용할 수 없는 P경우 형식의 패턴 입력 값(§11.1)T과 일치하는 패턴 P 이 프로그램에 나타나는 경우 T 컴파일 시간 오류입니다.
예제: 다음 예제에서는 컴파일 시간 형식
vTextReader이 이므로 컴파일 시간 오류를 생성합니다. 형식TextReader의 변수는 참조와 호환되는 값을 가질 수 없습니다.stringTextReader v = Console.In; // compile-time type of 'v' is 'TextReader' if (v is string) // compile-time error { // code assuming v is a string }그러나 컴파일 시간 형식
vobject이 이므로 다음에서는 컴파일 시간 오류를 생성하지 않습니다. 형식object의 변수에는 참조와 호환되는 값이 있을 수 있습니다.stringobject v = Console.In; if (v is string s) { // code assuming v is a string }끝 예제
각 패턴 폼은 패턴 이 런타임 시 값과 일치하는 값 집합을 정의합니다.
패턴 일치 중 작업 및 부작용 평가 순서(호출 Deconstruct, 속성 액세스 및 메서드 System.ITuple호출)는 지정되지 않았습니다.
11.2.2 선언 패턴
declaration_pattern 사용하여 값에 지정된 형식이 있는지 테스트하고, 테스트가 성공하면 필요에 따라 해당 형식의 변수에 값을 제공합니다.
declaration_pattern
: type simple_designation
;
simple_designation
: discard_designation
| single_variable_designation
;
discard_designation
: '_'
;
single_variable_designation
: identifier
;
토큰 이 포함된 _single_variable_designation 아닌 discard_designation 간주되어야 합니다.
값의 런타임 형식은 is-type 연산자(§12.15.12.1)에 지정된 것과 동일한 규칙을 사용하여 패턴의 형식에 대해 테스트됩니다. 테스트가 성공하면 패턴 이 해당 값과 일치 합니다. 형식이 nullable 값 형식 (§8.3.12) 또는 nullable 참조 형식(§8.9.3)인 경우 컴파일 시간 오류입니다. 이 패턴 형식은 값과 null 일치하지 않습니다.
참고: is-type 식
e is T과 선언 패턴e is T _은 nullable 형식이 아닌 경우T동일합니다. 끝 메모
패턴 입력 값(§11.1) e가 지정된 경우 simple_designationdiscard_designation 경우 무시(§9.2.9.2)를 표시하며 e 값은 아무것도 바인딩되지 않습니다. (이름이 _ 지정된 선언된 변수가 해당 시점에 범위에 있을 수 있지만 해당 명명된 변수는 이 컨텍스트에서 볼 수 없습니다.) 그렇지 않은 경우 simple_designation single_variable_designation 지정된 식별자가 명명한 지정된 형식의 지역 변수(§9.2.9)가 도입됩니다. 해당 지역 변수는 패턴이 값과 일치할 때 패턴 입력 값의 값이 할당됩니다.
패턴 입력 값과 지정된 형식의 정적 형식의 특정 조합은 호환되지 않는 것으로 간주되어 컴파일 시간 오류가 발생합니다. 정적 형식 E 의 값은 ID 변환, 암시적 또는 명시적 참조 변환, boxing 변환, unboxing 변환 또는 암시적 또는 명시적 nullable 값 형식 변환 이 있거나 열려 있는 형식(T)이 있는 경우 ET 형식과 ET 되는 패턴이라고 합니다. 형식 T 의 이름을 지정하는 선언 패턴은 패턴과 E 있습니다.
참고: 열린 형식에 대한 지원은 구조체 또는 클래스 형식일 수 있는 형식을 검사할 때 가장 유용할 수 있으며 boxing은 피해야 합니다. 끝 메모
예: 선언 패턴은 참조 형식의 런타임 형식 테스트를 수행하는 데 유용하며 관용구를 대체합니다.
var v = expr as Type; if (v != null) { /* code using v */ }약간 더 간결한
if (expr is Type v) { /* code using v */ }끝 예제
예: 선언 패턴을 사용하여 null 허용 형식의 값을 테스트할 수 있습니다. 형식
Nullable<T>값(또는 boxedT)은 값이 null이 아니고 null이 아니면 형식 패턴T2 id과T2T일치하거나 일부 기본 형식 또는 인터페이스와T일치합니다. 예를 들어 코드 조각에서int? x = 3; if (x is int v) { /* code using v */ }명령문
if의true조건은 런타임에 있으며 변수v는 블록 내의 형식3값을int보유합니다. 블록 후 변수v는 범위에 있지만 확실히 할당되지는 않습니다. 끝 예제
11.2.3 상수 패턴
constant_pattern 지정된 상수 값에 대해 패턴 입력 값(§11.1)의 값을 테스트하는 데 사용됩니다.
constant_pattern
: constant_expression
;
상수 패턴 P 은 있습니다T.
상수 패턴P의 경우 변환된 값은
- 패턴 입력 값의 형식이 정수 형식 또는 열거형 형식이면 패턴의 상수 값이 해당 형식으로 변환됩니다. 그렇지 않으면
- 패턴 입력 값의 형식이 정수 계열 형식 또는 열거형 형식의 nullable 버전이면 패턴의 상수 값이 기본 형식으로 변환됩니다. 그렇지 않으면
- 패턴의 상수 값 값입니다.
패턴 입력 값 e 및 변환된 값 P가 있는 상수 패턴 이 지정된 경우
- e에 정수 계열 형식 또는 열거형 형식 또는 해당 형식 중 하나의 nullable 형식이 있고 v에 정수 계열 형식이 있는 경우 패턴
P합니다. 그렇지 않으면 - 패턴
P합니다.
예: 다음 메서드의 문은
switch대/소문자 레이블에 5개의 상수 패턴을 사용합니다.static decimal GetGroupTicketPrice(int visitorCount) { switch (visitorCount) { case 1: return 12.0m; case 2: return 20.0m; case 3: return 27.0m; case 4: return 32.0m; case 0: return 0.0m; default: throw new ArgumentException(...); } }끝 예제
11.2.4 Var 패턴
var_pattern모든 값과 일치합니다. 즉, var_pattern 패턴 일치 작업은 항상 성공합니다.
var_pattern모든 형식에 적용할 수 있습니다.
var_pattern
: 'var' designation
;
designation
: simple_designation
| tuple_designation
;
tuple_designation
: '(' designations? ')'
;
designations
: designation (',' designation)*
;
패턴 입력 값(§11.1) e가 지정된 경우 지정 이 discard_designation 경우 무시(§9.2.9.2)를 표시하며 e 값은 아무것도 바인딩되지 않습니다. (해당 이름의 선언된 변수가 해당 시점에 범위에 있을 수 있지만 명명된 변수는 이 컨텍스트에서 볼 수 없습니다.) 그렇지 않으면 지정이 single_variable_designation 경우 런타임에 e의 값은 해당 형식이 e의 정적 형식이고 패턴 입력 값이 해당 지역 변수에 할당되는 해당 이름의 새로 도입된 지역 변수(§9.2.9)에 바인딩됩니다.
이름이 var var_pattern 사용되는 형식에 바인딩하는 경우 오류가 발생합니다.
지정이 tuple_designation 경우 패턴은 양식 지정의 positional_pattern((var)와 동일합니다.
) 여기서 지정은 tuple_designation 내에서 찾을 수 있습니다. 예를 들어 패턴 var (x, (y, z)) 은 .에 해당합니다 (var x, (var y, var z)).
11.2.5 위치 패턴
positional_pattern 입력 값이 아닌지 null확인하고, 적절한 Deconstruct 메서드(§12.7)를 호출하고, 결과 값에 대한 추가 패턴 일치를 수행합니다. 또한 입력 값의 형식이 포함된 Deconstruct형식과 같거나 입력 값의 형식이 튜플 형식이거나 입력 objectSystem.ITuple 값의 형식이 튜플 형식이고 식의 런타임 형식이 구현되는 경우 튜플과 유사한 패턴 구문을 지원합니다 System.ITuple.
positional_pattern
: type? '(' subpatterns? ')' property_subpattern? simple_designation?
;
subpatterns
: subpattern (',' subpattern)*
;
subpattern
: pattern
| subpattern_name ':' pattern
;
subpattern_name
: identifier
| subpattern_name '.' identifier
;
입력 값이 패턴 형식(하위 패턴)과 일치하는 경우 형식에서 액세스 가능한 선언을 검색하고 분해 선언 Deconstruct 과 동일한 규칙을 사용하여 해당 선언 중 하나를 선택하여 메서드를 선택합니다.
positional_pattern 형식을 생략하고, 식별자가 없는 단일 하위 요소가 있고, property_subpattern 없고, simple_designation 없는 경우 오류입니다. 이는 괄호로 괄호로 constant_patternpositional_pattern 간에 구분됩니다.
목록의 패턴과 일치하는 값을 추출하려면
- 형식을 생략하고 입력 식의 형식이 튜플 형식인 경우 하위pattern의 수는 튜플의 카디널리티와 같아야 합니다. 각 튜플 요소는 해당 하위 패턴과 일치하며, 이러한 요소가 모두 성공하면 일치가 성공합니다. 하위pattern에 식별자가 있는 경우 튜플 형식의 해당 위치에 있는 튜플 요소의 이름을 지정해야 합니다.
- 그렇지 않으면 적합한
Deconstruct형식의 멤버로 존재하는 경우 입력 값의 형식이 형식과 패턴 호환되지 않는 경우 컴파일 시간 오류입니다. 런타임에 입력 값이 형식에 대해 테스트됩니다. 실패하면 위치 패턴 일치가 실패합니다. 성공하면 입력 값이 이 형식으로 변환되고Deconstruct출력 매개 변수를 수신하기 위해 새로 컴파일러에서 생성된 변수로 호출됩니다. 수신된 각 값은 해당 하위 패턴과 일치하며, 이러한 값이 모두 성공하면 일치가 성공합니다. 하위pattern에 식별자가 있는 경우 해당 위치의Deconstruct매개 변수 이름을 지정해야 합니다. - 그렇지 않은 경우 형식 을 생략하고 입력 값이 형식
object이거나 암시적 참조 변환으로System.ITuple변환할 수 있는 일부 형식이고 하위 요소 사이에 식별자가 나타나지 않으면 일치 항목이 사용됩니다System.ITuple. - 그렇지 않으면 패턴이 컴파일 시간 오류입니다.
런타임에 서브패턴이 일치하는 순서는 지정되지 않으며, 실패한 일치가 모든 하위pattern과 일치하려고 시도하지 않을 수 있습니다.
예제: 여기서는 식 결과를 분해하고 결과 값을 해당 중첩 패턴과 일치합니다.
static string Classify(Point point) => point switch { (0, 0) => "Origin", (1, 0) => "positive X basis end", (0, 1) => "positive Y basis end", _ => "Just a point", }; public readonly struct Point { public int X { get; } public int Y { get; } public Point(int x, int y) => (X, Y) = (x, y); public void Deconstruct(out int x, out int y) => (x, y) = (X, Y); }끝 예제
예: 다음과 같이 위치 패턴에서 튜플 요소 및 분해 매개 변수의 이름을 사용할 수 있습니다.
var numbers = new List<int> { 10, 20, 30 }; if (SumAndCount(numbers) is (Sum: var sum, Count: var count)) { Console.WriteLine($"Sum of [{string.Join(" ", numbers)}] is {sum}"); } static (double Sum, int Count) SumAndCount(IEnumerable<int> numbers) { int sum = 0; int count = 0; foreach (int number in numbers) { sum += number; count++; } return (sum, count); }생성된 출력은 다음과 같습니다.
Sum of [10 20 30] is 60끝 예제
11.2.6 속성 패턴
property_pattern 입력 값이 아닌지 null확인하고 액세스 가능한 속성 또는 필드를 사용하여 추출된 값과 재귀적으로 일치합니다.
property_pattern
: type? property_subpattern simple_designation?
;
property_subpattern
: '{' '}'
| '{' subpatterns ','? '}'
;
property_pattern 하위 페이지에subpattern_name 포함되어 있지 않으면 오류가 발생합니다.
형식이 nullable 값 형식 (§8.3.12) 또는 nullable 참조 형식(§8.9.3)인 경우 컴파일 시간 오류입니다.
참고: null 검사 패턴은 사소한 속성 패턴에서 제외됩니다. 문자열
s이 null이 아닌지 확인하려면 다음 형식 중 하나를 작성할 수 있습니다.#nullable enable string s = "abc"; if (s is object o) ... // o is of type object if (s is string x1) ... // x1 is of type string if (s is {} x2) ... // x2 is of type string if (s is {}) ...끝 메모
식 e가 패턴 형식{하위} 패턴과 일치하는 경우 식 e가 형식별로 지정된 T 형식과 패턴 호환되지 않는 경우 컴파일 시간 오류입니다. 형식이 없는 경우 형식은 e의 정적 형식으로 간주됩니다.
하위 subpattern_name 왼쪽에 나타나는 각 subpattern_name 액세스 가능한 읽기 가능한 속성 또는 T 필드를 지정해야 합니다. property_pattern simple_designation 있으면 T 형식의 패턴 변수 를 선언합니다.
런타임 시 식은 T에 대해 테스트됩니다. 실패하면 속성 패턴 일치가 실패하고 결과는 .입니다 false. 성공하면 각 property_subpattern 필드 또는 속성이 읽혀지고 해당 값이 해당 패턴과 일치합니다. 전체 일치 false 의 결과는 이들 중 하나의 결과가 .인 경우에만 발생합니다 false. 서브패턴이 일치하는 순서는 지정되지 않으며, 실패한 일치는 런타임에 모든 하위 페턴을 테스트하지 않을 수 있습니다. 일치가 성공하고 property_pattern simple_designationsingle_variable_designation 경우 선언된 변수에 일치하는 값이 할당됩니다.
이 property_pattern 무명 형식과 패턴 일치에 사용할 수 있습니다.
subpattern_name 중첩 멤버를 참조할 수 있습니다. 이러한 경우 각 이름 조회에 대한 수신기는 property_pattern입력 형식에서 시작하여 이전 멤버 T의 형식입니다.
T가 nullable 형식인 경우 T 는 기본 형식이고, 그렇지 않으면 T 는 T와 같습니다. 예를 들어 폼 { Prop1.Prop2: pattern } 의 패턴은 정확히 같습니다{ Prop1: { Prop2: pattern } }.
참고: T 가 nullable 값 형식 또는 참조 형식인 경우 null 검사가 포함됩니다. 이 null 검사는 사용할 수 있는 중첩 속성이 T가 아닌 T의 속성이 됨을 의미합니다. 반복되는 멤버 경로가 허용되므로 패턴 일치의 컴파일은 패턴의 공통 부분을 활용할 수 있습니다. 끝 메모
예제:
var o = ...; if (o is string { Length: 5 } s) ...끝 예제
예: 다음과 같이 런타임 형식 검사 및 변수 선언을 속성 패턴에 추가할 수 있습니다.
Console.WriteLine(TakeFive("Hello, world!")); // output: Hello Console.WriteLine(TakeFive("Hi!")); // output: Hi! Console.WriteLine(TakeFive(new[] { '1', '2', '3', '4', '5', '6', '7' })); // output: 12345 Console.WriteLine(TakeFive(new[] { 'a', 'b', 'c' })); // output: abc static string TakeFive(object input) => input switch { string { Length: >= 5 } s => s.Substring(0, 5), string s => s, ICollection<char> { Count: >= 5 } symbols => new string(symbols.Take(5).ToArray()), ICollection<char> symbols => new string(symbols.ToArray()), null => throw new ArgumentNullException(nameof(input)), _ => throw new ArgumentException("Not supported input type."), };생성된 출력은 다음과 같습니다.
Hello Hi! 12345 abc끝 예제
11.2.7 무시 패턴
모든 식은 무시 패턴과 일치하므로 식 값이 삭제됩니다.
discard_pattern
: '_'
;
폼 relational_expression 패턴의 relational_expression삭제 패턴을 사용하거나 is 패턴으로 사용하는 것은 컴파일 시간 오류입니다.
참고: 이러한 경우 식과 일치하려면 삭제
var _와 함께 var_pattern 사용합니다. 끝 메모
예제:
Console.WriteLine(GetDiscountInPercent(DayOfWeek.Friday)); Console.WriteLine(GetDiscountInPercent(null)); Console.WriteLine(GetDiscountInPercent((DayOfWeek)10)); static decimal GetDiscountInPercent(DayOfWeek? dayOfWeek) => dayOfWeek switch { DayOfWeek.Monday => 0.5m, DayOfWeek.Tuesday => 12.5m, DayOfWeek.Wednesday => 7.5m, DayOfWeek.Thursday => 12.5m, DayOfWeek.Friday => 5.0m, DayOfWeek.Saturday => 2.5m, DayOfWeek.Sunday => 2.0m, _ => 0.0m, };생성된 출력은 다음과 같습니다.
5.0 0.0 0.0여기서 무시 패턴은 처리에 사용되며 열거형의
null해당 멤버가 없는 정수 값은 모두 처리DayOfWeek합니다. 이렇게 하면 식이switch가능한 모든 입력 값을 처리합니다. 끝 예제
11.2.8 형식 패턴
type_pattern 패턴 입력 값(§11.1)에 지정된 형식이 있는지 테스트하는 데 사용됩니다.
type_pattern
: type
;
형식 이름을 지정하는 형식 T 패턴은 패턴과 T 호환되는 E 모든 형식 E 에 적용할 수 있습니다(§11.2.2).
값의 런타임 형식은 is-type 연산자(§12.15.12.1)에 지정된 것과 동일한 규칙을 사용하여 형식에 대해 테스트됩니다. 테스트가 성공하면 패턴이 해당 값과 일치합니다. 형식이 nullable 형식 인 경우 컴파일 시간 오류입니다. 이 패턴 형식은 값과 null 일치하지 않습니다.
11.2.9 관계형 패턴
relational_pattern 패턴 입력 값(§11.1)을 상수 값에 대해 관계형으로 테스트하는 데 사용됩니다.
relational_pattern
: '<' relational_expression
| '<=' relational_expression
| '>' relational_expression
| '>=' relational_expression
;
상수 값으로 평가하려면 relational_pattern relational_expression 필요합니다.
관계형 패턴은 관계형 연산자, <및 이러한 이진 관계형 연<=산자를 지원하는 모든 기본 제공 형식을 지원합니다. 두 피연산자가 같은 형식을 갖는 경우 ( >, >=, sbyte, byte, short, ushortint, uint, longulongcharfloatdoubledecimal및 열거형)nintnuint
적절한 기본 제공 이진 관계형 연산자가 형식 의 피연산자를 모두 사용하여 정의되거나 명시적 nullable 또는 unboxing 변환이 상수 식의 형식으로 T 존재하는 경우 relational_pattern 형식T에 T할 수 있습니다.
식이 null 상수로 계산double.NaNfloat.NaN되는 경우 컴파일 시간 오류입니다.
입력 값에 적합한 기본 제공 이진 관계형 연산자가 정의된 형식이 있는 경우 해당 연산자의 평가가 관계형 패턴의 의미로 사용됩니다. 그렇지 않으면 입력 값이 명시적 nullable 또는 unboxing 변환을 사용하여 상수 식의 형식으로 변환됩니다. 이러한 변환이 없으면 컴파일 시간 오류입니다. 변환에 실패하면 패턴이 일치하지 않는 것으로 간주됩니다. 변환이 성공하면 패턴 일치 작업의 결과는 변환된 입력이 있는 e «op» v 식을 e 평가한 결과이고, «op»은 관계형 연산자이며 v 상수 식입니다.
예제:
Console.WriteLine(Classify(13)); Console.WriteLine(Classify(double.NaN)); Console.WriteLine(Classify(2.4)); static string Classify(double measurement) => measurement switch { < -4.0 => "Too low", > 10.0 => "Too high", double.NaN => "Unknown", _ => "Acceptable", };생성된 출력은 다음과 같습니다.
Too high Unknown Acceptable끝 예제
11.2.10 논리 패턴
logical_pattern 패턴 일치의 결과를 부정하거나 결합() 또는 분리(andor)를 사용하여 여러 패턴 일치의 결과를 결합하는 데 사용됩니다.
logical_pattern
: disjunctive_pattern
;
disjunctive_pattern
: disjunctive_pattern 'or' conjunctive_pattern
| conjunctive_pattern
;
conjunctive_pattern
: conjunctive_pattern 'and' negated_pattern
| negated_pattern
;
negated_pattern
: 'not' negated_pattern
| primary_pattern
;
not, and및 or집합적으로 패턴 연산자라고 합니다.
부정되는 패턴이 일치하지 않는 경우 negated_pattern 일치하며 그 반대의 경우도 마찬가지입니다.
conjunctive_pattern 일치하려면 두 패턴이 모두 필요합니다.
disjunctive_pattern 일치하려면 패턴이 필요합니다. 해당 언어 연산자와 &&||andor 달리 단락 연산자는 아닙니다.
패턴 변수가 또는 not 패턴 연산자 아래에 선언되는 것은 컴파일 시간 오류입니다or.
참고: 패턴 변수에 대한 명확한 할당을 생성하거나
not생성할 수 없or으므로 해당 위치에서 하나를 선언하는 것은 오류입니다. 끝 메모
conjunctive_pattern 두 번째 패턴의 입력 형식은 첫 번째 패턴의 형식 축소 요구 사항에 따라 좁혀집니다and. 패턴 의 P은 다음과 같이 정의됩니다.
- 형식 패턴인 경우
P좁은 형식은 형식 패턴 형식의 형식입니다. - 그렇지 않은 경우 선언 패턴인 경우
P좁은 형식 은 선언 패턴 형식의 형식입니다. - 그렇지 않은 경우 명시적 형식을 제공하는 재귀 패턴인 경우
P좁혀진 형식 은 해당 형식입니다. - 그렇지 않은 경우 positional_pattern(§11.2.5)에 대한
ITuple규칙을 통해 일치하는 경우P좁혀진 형식은 형식System.ITuple입니다. - 그렇지 않은 경우 상수가 null 상수가 아니고 식에
P으로 상수 식 변환이 없는 상수 패턴이면 좁은 형식은 상수의 형식입니다. - 그렇지 않은 경우 상수 식에
P으로의 상수 식 변환이 없는 관계형 패턴인 경우 좁혀진 형식은 상수의 형식입니다. - 그렇지 않은 경우 패턴인
P경우or축소된 형식은 이러한 공통 형식이 있는 경우 하위 패턴의 축소된 형식의 공통 형식입니다. 이를 위해 공통 형식 알고리즘은 ID, boxing 및 암시적 참조 변환만 고려하고 패턴 시퀀or스의 모든 하위 패턴(괄호 처리된 패턴 무시)을 고려합니다. - 그렇지 않은 경우 패턴인
P경우and좁은 형식은 오른쪽 패턴의 좁은 형식입니다. 또한 왼쪽 패턴의 좁은 형식 은 오른쪽 패턴의 입력 형식 입니다. - 그렇지 않으면 좁혀진 형식 이
P'의 입력 형식입니다P.
참고: 문법
not에 표시된 대로 우선 순위and가 1보다 우선합니다or. 괄호를 사용하여 명시적으로 표시하거나 재정의할 수 있습니다. 끝 메모
패턴이 오른쪽is에 나타나면 패턴의 범위는 문법에 의해 결정됩니다. 결과적으로 패턴 연산자 및 and 패턴 내의 패턴은 논리 연산ornot&&||자보다 더 단단히 바인딩되고 ! 패턴 외부에는 더 밀접하게 바인딩됩니다.
예제:
Console.WriteLine(Classify(13)); Console.WriteLine(Classify(-100)); Console.WriteLine(Classify(5.7)); static string Classify(double measurement) => measurement switch { < -40.0 => "Too low", >= -40.0 and < 0 => "Low", >= 0 and < 10.0 => "Acceptable", >= 10.0 and < 20.0 => "High", >= 20.0 => "Too high", double.NaN => "Unknown", };생성된 출력은 다음과 같습니다.
High Too low Acceptable끝 예제
예제:
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 1, 19))); Console.WriteLine(GetCalendarSeason(new DateTime(2021, 10, 9))); Console.WriteLine(GetCalendarSeason(new DateTime(2021, 5, 11))); static string GetCalendarSeason(DateTime date) => date.Month switch { 3 or 4 or 5 => "spring", 6 or 7 or 8 => "summer", 9 or 10 or 11 => "autumn", 12 or 1 or 2 => "winter", _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."), };생성된 출력은 다음과 같습니다.
winter autumn spring끝 예제
예제:
object msg = "msg"; object obj = 5; bool flag = true; // This is parsed as: (msg is (not int) or string) result = msg is not int or string; Console.WriteLine($"msg (\"msg\"): msg is not int or string: {result}"); // This is parsed as: (obj is (int or string)) && flag bool result = obj is int or string && flag; Console.WriteLine($"obj (5), flag (true): obj is int or string && flag: {result}"); // This is parsed as: (obj is int) || ((obj is string) && flag) result = obj is int || obj is string && flag; Console.WriteLine($"obj (5), flag (true): obj is int || obj is string && flag: {result}"); flag = false; // This is parsed as: (obj is (int or string)) && flag result = obj is int or string && flag; Console.WriteLine($"obj (5), flag (false): obj is int or string && flag: {result}"); // This is parsed as: (obj is int) || ((obj is string) && flag) result = obj is int || obj is string && flag; Console.WriteLine($"obj (5), flag (false): obj is int || obj is string && flag: {result}");생성된 출력은 다음과 같습니다.
msg ("msg"): msg is not int or string: True obj (5), flag (true): obj is int or string && flag: True obj (5), flag (true): obj is int || obj is string && flag: True obj (5), flag (false): obj is int or string && flag: False obj (5), flag (false): obj is int || obj is string && flag: True끝 예제
11.3 패턴 하위 요소
switch 문에서 앞의 보호되지 않은 사례 집합(§13.8.3)에 의해 사례 패턴이 하위화되면 오류가 발생합니다. 비공식적으로 이는 입력 값이 이전 사례 중 하나와 일치했음을 의미합니다. 다음 규칙은 패턴 집합이 지정된 패턴을 하위로 사용하는 경우를 정의합니다.
P 패턴은 다음 조건 중 하나라도 유지되는 경우 상수 K 와 일치합니다.
- 해당 패턴의 런타임 동작에 대한 사양은 일치
P합니다K. -
P는 형식 에 대한T아니며K런타임 형식null이K아닌T경우 또는 파생된T형식 또는 구현하는 형식입니다T. -
P은 연산자 «op» 및 상수가 있는v,와K식 «op»v이 계산됩니다true. -
P는 negated_patternnot P₁일치P₁K하지 않습니다. -
P는 conjunctive_patternP₁ and P₂일치하고P₁K일치P₂K합니다. -
P는 disjunctive_patternP₁ or P₂일치P₁하거나K일치P₂K합니다. -
P는 discard_pattern.
패턴 집합은 Q로 설정합니다.
-
P는 상수 패턴이며 집합Q의 모든 패턴이 '의P과 일치합니다. -
P은 var 패턴이고 패턴Q입력 값의 형식(§11.1)에 대해 패턴 집합이 완전하고(§11.4) 패턴 입력 값이 nullable 형식이 아니거나 일부 패턴Q이 일치null합니다. -
P는 형식T이 있는 선언 패턴이며 패턴Q집합은 합니다(T). -
P는 형식 에 대한T패턴 집합Q이 형식에 대해T합니다. -
P는 연산자 «op» 및 상수 값이 있는v이며, «op»v관계를 만족하는 입력 형식의 모든 값에 대해 집합Q의 일부 패턴은 해당 값과 일치합니다. -
P는 disjunctive_patternP₁ or P₂및 패턴 집합이Q하위P₁열거 및Q하위 수P₂입니다. -
P는 conjunctive_patternP₁ and P₂다음 중 하나 이상을 보유Q합니다. subsumesP₁또는QsubsumesP₂. -
P는 negated_patternnot P₁이며Q일치 하지 않는 값만 고려 하는 입력 형식에 대 한P₁한 . -
P는 discard_pattern 패턴 입력 값의 형식에 대해 패턴Q집합이 완전 하며 패턴 입력 값이 nullable 형식이 아니거나 일부 패턴Q이 일치null합니다. - 일부 패턴
Q은 disjunctive_patternQ₁ or Q₂해당 패턴을 inQ₁으로Q바꿔서 하위P집합을 생성하거나 이를 대체하면Q₂하위 집합이 생성됩니다P. - 일부 패턴
Q은 negated_patternnot Q₁일치시킬P값과Q₁일치하지 않습니다.
11.4 패턴 완전성
비공식적으로, null 이외의 해당 형식의 가능한 모든 값에 대해 집합의 일부 패턴을 적용할 수 있는 경우 형식에 대해 패턴 집합이 완전합니다. 다음 규칙은 패턴 집합이 형식에 대해 완전할 때를 정의합니다.
다음 조건이 있는 경우 형식 Q 에 대해 패턴 T합니다.
-
T은 정수 또는 열거형 형식이거나 그 중 하나의 nullable 버전이며, nullable이 아닌 기본 형식의T가능한 모든 값에Q대해 일부 패턴이 해당 값과 일치합니다. - 일부 패턴
Q은 var 패턴입니다. - 일부 패턴은 형식
Q에 대한D이며 ID 변환, 암시적 참조 변환 또는 boxing 변환이TD있습니다. - 일부 패턴
Q은 형식에 대한DID 변환, 암시적 참조 변환 또는 boxing 변환이TD있습니다. - 일부 패턴
Q은 discard_pattern; 또는 - 패턴
Q에는 범위가 nullable이 아닌 기본 형식의 가능한 모든 값을 집합적으로 포함하는T조합이 포함됩니다.float및 형식의 경우double관계형 패턴과 일치하지 않으므로 이 항목이 포함되거나System.Double.NaN각각System.Single.NaN포함NaN됩니다. - 일부 패턴
Q은 disjunctive_patternP₁ or P₂해당 패턴을 둘 다P₁로P₂바꿔서 ; 또는 에Q대해T집합을 생성합니다. - 일부 패턴
Q은 negated_patternnot P₁패턴이며 패턴과Q일치하는 값P₁은 가능한 모든 값을T덮습니다. negated_patternnot P₁가능한 값이 없는 경우P₁그 자체로 완전합니다.T - 일부 패턴
Q은 conjunctive_patternP₁ and P₂있으며, 포함된 집합만P₁완전T하며 포함된 집합만P₂완전합니다T.
참고: 형식 패턴에 nullable 형식이 포함된 경우 형식 패턴이 값과 일치하지
null않으므로 형식에 대해 패턴이 완전하지만 여전히 경고가 생성될 수 있습니다. 끝 메모
참고: 부동 소수점 형식의 경우 두 관계형 패턴이 모두 일치하지
< 0않으므로 패턴>= 0의 조합이 완전NaN. 올바른 완전 집합은 , 및< 0(또는>= 0)입니다double.NaN.float.NaN끝 메모
예제:
static void M(byte b) { switch (b) { case 0: case 1: case 2: ... // handle every specific value of byte break; // error: the pattern 'byte other' is subsumed by the (exhaustive) // previous cases case byte other: break; } }끝 예제
ECMA C# draft specification