成果物
情報源
- https://docs.microsoft.com/ja-jp/dotnet/csharp/tutorials/pattern-matching
- https://ufcpp.net/study/csharp/datatype/patterns/?p=1
例によって公式サイトがクソわかりにくい。外部サイトが超わかりやすかったので、そっちを参考にする。
マッチパターン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. 宣言パターン(非再帰)
変数x
がint
型であるか確認する。
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
パターンは利用頻度が少なそう。覚えなくていいかも?
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13 ※
- bash 4.4.12(1)-release ※
- SQLite 3.29.0 ※
- C# dotnet 3.0.100
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux ``