次の方法で共有


11 パターンとパターン マッチング

11.1 全般

pattern は構文形式であり、is演算子 (§12.12.12) とswitch_statement (§13.8.3) で使用して、受信データの比較対象となるデータの形状を表すことができます。 パターンは、switch ステートメントのに対して、またはis演算子の左側にあるrelational_expressionに対してテストされ、それぞれがパターン入力値と呼ばれます

11.2 パターン形式

11.2.1 全般

パターンには、次のいずれかの形式があります。

pattern
    : declaration_pattern
    | constant_pattern
    | var_pattern
    ;

declaration_patternvar_patternにより、ローカル変数が宣言される可能性があります。

各パターン フォームは、パターンを適用できる入力値の型のセットを定義します。 パターン Pパターンが一致する可能性のある値を持つ型の中にTがある場合にT型に適用できます。 PTに適用できない場合、パターンPT型のパターン入力値 (§11.1) と一致するようにプログラムに表示される場合、コンパイル時エラーになります。

: 次の例では、 v のコンパイル時の型が TextReaderされているため、コンパイル時エラーが生成されます。 TextReader型の変数は、stringと参照互換の値を持つことはありません。

TextReader v = Console.In; // compile-time type of 'v' is 'TextReader'
if (v is string) // compile-time error
{
    // code assuming v is a string
}

ただし、 v のコンパイル時の型が objectされているため、次のコードではコンパイル時エラーは生成されません。 object型の変数は、stringと参照互換の値を持つことができます。

object v = Console.In;
if (v is string s)
{
    // code assuming v is a string
}

end の例

各パターン フォームは、パターンが実行時に値 照合 値のセットを定義します。

11.2.2 宣言パターン

declaration_patternは、値に特定の型があることをテストするために使用され、テストが成功した場合は、その型の変数に値を指定します。

declaration_pattern
    : type simple_designation
    ;
simple_designation
    : single_variable_designation
    ;
single_variable_designation
    : identifier
    ;

値のランタイム型は、is-type 演算子 (§12.12.12.1) で指定されたのと同じ規則を使用して、パターン内の type に対してテストされます。 テストが成功すると、その値パターン照合されます。 type が null 許容値型 (§8.3.12) の場合、コンパイル時エラーです。 このパターン フォームは、 null 値と一致しません。

: is-type 式 e is T と宣言パターン e is T _ は、 T が null 許容型でない場合と同等です。 end note

パターン入力値 (§11.1) eを指定すると simple_designation識別子である場合 _破棄 (§9.2.9.1) を表し、 e の値は何にもバインドされません。 ( _ という名前の宣言された変数は、その時点でスコープ内にある場合がありますが、その名前付き変数はこのコンテキストでは表示されません)。 simple_designation が他の識別子である場合は、指定された識別子によって指定された型のローカル変数 (§9.2.9) が導入されます。 そのローカル変数には、パターンが マッチしたときに、その値 パターン入力値の値が割り当てられます。

パターン入力値と特定の型の静的型の特定の組み合わせは互換性がないとみなされ、コンパイル時エラーが発生します。 静的型Eの値は、id 変換、暗黙的または明示的な参照変換、ボックス化変換、EからTへのボックス化解除の変換、またはEまたはTのいずれかが開いている型 (§8.4.3) がある場合に型とT互換性があると言われます。 T型に名前を付ける宣言パターンはETと互換性のあるすべての型Eに適用できます。

: オープン型のサポートは、構造体型またはクラス型である可能性がある型をチェックする場合に最も役立ち、ボックス化は避ける必要があります。 end note

: 宣言パターンは、参照型の実行時の型テストを実行するのに役立ち、イディオムを置き換えます

var v = expr as Type;
if (v != null) { /* code using v */ }

少し簡潔に

if (expr is Type v) { /* code using v */ }

end の例

typeが null 許容値型の場合はエラーです。

: 宣言パターンは、null 許容型の値をテストするために使用できます。型Nullable<T> (またはボックス化されたT) の値は、値が null 以外で T2 idT2T場合、またはTの基本型またはインターフェイスの型パターンと一致します。 たとえば、コード フラグメント内

int? x = 3;
if (x is int v) { /* code using v */ }

if ステートメントの条件は実行時にtrueされ、変数vはブロック内でint型の値3を保持します。 end の例

11.2.3 定数パターン

constant_patternは、パターン入力値 (§11.1) の値を特定の定数値に対してテストするために使用されます。

constant_pattern
    : constant_expression
    ;

定数パターンPPの定数式から型Tへの暗黙的な変換がある場合、型Tに適用できます。

定数パターン Pの場合、その 変換された値

  • パターン入力値の型が整数型または列挙型の場合、パターンの定数値はその型に変換されます。然も無くば
  • パターン入力値の型が整数型または列挙型の null 許容バージョンである場合、パターンの定数値は基になる型に変換されます。然も無くば
  • パターンの定数値の値。

パターン入力値がe変換された値を持つ定数パターンPv

  • eが整数型または列挙型、またはいずれかの null 許容形式を持ち、v が整数型を持つ場合、パターンP マッチe == vの結果がtrue場合は値e。それ以外の場合
  • object.Equals(e, v)trueを返す場合はパターン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(...);
    }
}

end の例

11.2.4 Var パターン

var_pattern matchesすべての値。 つまり、 var_pattern を使用したパターン マッチング操作は常に成功します。

var_patternすべての型に適用できます。

var_pattern
    : 'var' designation
    ;
designation
    : simple_designation
    ;

パターン入力値 (§11.1) eを指定すると デザイン識別子 _の場合、破棄 (§9.2.9.1) を示し、 e の値は何にもバインドされません。 (その名前を持つ宣言された変数は、その時点でスコープ内にある場合がありますが、このコンテキストではその名前付き変数は表示されません)。 designation が他の識別子である場合、実行時に e の値はその名前の新しく導入されたローカル変数 (§9.2.9) にバインドされ、その型は e の静的な型であり、パターン入力値はそのローカル変数に割り当てられます。

var_patternが使用されている型にvar名前がバインドされると、エラーになります。

11.3 パターンのサブ再開

switch ステートメントでは、前の一連の非ガード ケース (§13.8.3) によって、ケースのパターンがsubsumed場合はエラーになります。 非公式には、これは、入力値が前のいずれかのケースで一致したことを意味します。 次の規則は、一連のパターンが特定のパターンをサブスムするタイミングを定義します。

パターンが一致P そのパターンのランタイム動作の仕様がKに一致P場合は定数K

一連のパターン Q subsumes 次のいずれかの条件が満たされている場合に P パターンです。

  • P は定数パターンであり、セット Q 内のすべてのパターンが P変換された値と一致します
  • Pは var パターンであり、パターン入力値の型 (§11.1) に対してQパターンのセットが exhaustive (§11.4) であり、パターン入力値が null 許容型でないか、Qのパターンがnullに一致します。
  • Pは型Tを持つ宣言パターンであり、型T (§11.4) に対してQパターンのセットがです。

11.4 パターンの網羅性

非公式には、null 以外の型のすべての可能な値に対して、セット内のパターンが適用される場合、パターンのセットは完全です。 次の規則は、一連のパターンが型に対していつ 完全 するかを定義します。

次のいずれかの条件が満たされている場合、型TQ一連のパターンは完全です。

  1. T は整数型または列挙型、またはいずれかの null 許容バージョンであり、 Tの null 非許容基になる型のすべての可能な値に対して、 Q のパターンはその値と一致します。
  2. Qの一部のパターンは、var パターン; または
  3. Qのパターンの中には、型D宣言パターンがあり、ID 変換、暗黙的な参照変換、またはTからDへのボックス化変換があります。

例:

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;
    }
}

end の例