やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

C#7.0パターンマッチング

 C#7.0までで使える非再帰パターンマッチングについて。

成果物

情報源

 例によって公式サイトがクソわかりにくい。外部サイトが超わかりやすかったので、そっちを参考にする。

マッチパターン6種

 マッチパターンは全部で以下の6種あるらしい。

パターン C# ver 概要
宣言パターン 7.0 型の判定 int i, string s
定数パターン 7.0 定数との比較 null, 1
var パターン 7.0 何にでもマッチ・変数で受け取り var x
破棄パターン 8.0 何にでもマッチ・無視 _
位置パターン 8.0 分解と同じ要領で、再帰的にマッチングする (1, var i, _)
プロパティ パターン 8.0 プロパティに対して再帰的にマッチングする { A: 1, B: var i }

 C#7.0で追加されたものは非再帰パターンで1層かぎり。8.0で追加されたものは再帰パターンで何層でも可。

C# ver 違い
C#7.0 再帰パターン
C#8.0 再帰パターン

 これらのパターンは以下のような構文で使う。特定の構文内でしか使えないパターンもある。

今回

 簡単な非再帰パターンだけやる。

1. 宣言パターン(非再帰

 変数xint型であるか確認する。

if (x is int i) {}

 確認した型の変数sを使って、その型に固有のメンバLengthを呼び出す。

if (x is string s) { return s.Length; }

 switch文なら以下のように使う。

switch (x) {
    case int i:
        break;
    case string s:
        break;
    default: 
        break;
}

2. 定数パターン(非再帰

if (x is int 5) {}
if (x is "なんか文字列") {}
switch (x) {
    case 5:
        break;
    case "なんか文字列":
        break;
    default: 
        break;
}

3. varパターン(非再帰

 宣言パターンの型をvarにした版。

switch (x)
{
    // 定数パターン
    case 0: return 0;
    // 宣言パターン
    case string s: return s.Length;
    // varパターン(nullにもヒットしてしまう!)
    case var v: return v.ToString().Length;
}

 varパターンはnullにもヒットしてしまう。よって上記コードのvarパターンにnullがヒットしたときはToString()のところでNullReferenceException例外が発生する。

 それを回避するため、varパターンの前に定数パターンでnullを書いておく。以下のように。

switch (x)
{
    // 定数パターン
    case 0: return 0;
    // 宣言パターン
    case string s: return s.Length;
    // varパターンはnullにもヒットしてしまいNullReferenceExceptionになるのでここで回避
    case null: return -1;
    // varパターン(nullにもヒットしてしまう!)
    case var v: return v.ToString().Length;
}

 また、一応isでも使える。意味はない。

if (x is var v) { Console.WriteLine("何かしらの型。絶対ヒットする。nullすらも。"); }
else { Console.WriteLine("何の型でもない。ヒットしえない。"); }

 varパターンは利用頻度が少なそう。覚えなくていいかも?

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux
``