C#11ではリストパターンが使えるようになった。
概要
C# 11 ではリストパターンが使えるようになりました。
この記事では外部から読み取ったcsv様のデータをパースする例を通して、リストパターンの使い方を確認したいと思います。
リストパターンって?
公式ドキュメントに説明があります。
配列に対して、与えられたパターンに一致するかどうかを確認するパターンです。
例
csv様のデータをパースする例を通してリストパターンの使い方を確認します。
設定
以下のようなrecordが定義されているとします。
abstract record 部品;
record 部品α(int 縦サイズ, int 横サイズ) : 部品;
record 部品β(int 半径) : 部品;
record 部品γ(string メーカー) : 部品;
record 部品δ(string[] メーカーたち, string メインのメーカー) : 部品;
record 部品ε(int 寸法) : 部品;
外部から読み取った次のようなstring[][]
データを、List<部品>
にパースしたいとします。
string[][] 生備品リスト = new string[][] {
new []{"部品β", "3"},
new []{"部品α","10", "15"},
new []{"部品β", "4"},
new []{"部品γ", "A社"},
new []{"部品β", "8"},
new []{"部品α", "3", "7"},
new []{"部品β", "10"},
new []{"部品δ", "A社", "B社", "C社", "B社"},
new []{"部品ε", "コメント数3", "10", "コメント:この部品は廃止される", "コメント2:廃止年度は2026年", "コメント3:大体部品の検討中"}
};
コード
以下の書き方で目的が達成できます。
List<部品> 備品リスト = 生備品リスト.Select<string[], 部品>(行 => 行 switch
{
["部品α", var 縦, var 横] => new 部品α(int.Parse(縦), int.Parse(横)),
["部品β", var 半径] => new 部品β(int.Parse(半径)),
["部品γ", var メーカー] => new 部品γ(メーカー),
["部品δ", .. var メーカーたち, var メインのメーカー] => new 部品δ(メーカーたち, メインのメーカー),
["部品ε", _, var 寸法, ..] => new 部品ε(int.Parse(寸法)),
_ => throw new Exception($"不正なデータ。[{string.Join(' ', 行)}]はパース出来ません。"),
}).ToList();
出力してみると、正しく読み取れていることがわかります。
foreach (部品 備品 in 備品リスト)
{
Console.WriteLine(備品);
}
出力:
部品β { 半径 = 3 }
部品α { 縦サイズ = 10, 横サイズ = 15 }
部品β { 半径 = 4 }
部品γ { メーカー = A社 }
部品β { 半径 = 8 }
部品α { 縦サイズ = 3, 横サイズ = 7 }
部品β { 半径 = 10 }
部品δ { メーカーたち = System.String[], メインのメーカー = B社 }
部品ε { 寸法 = 10 }
説明
パターンαの説明
パターン ["a", "b", "c"]
は、一番目の要素が"a"
, 二番目の要素が"b"
、三番目の要素が"c"
であって、それ以降に要素が続かないような配列にマッチします。
たとえば["部品α", var 縦, var 横]
であれば、長さ3の配列であって、一番目の要素が"部品α"
であるものにマッチし、2番目の要素が変数縦
、3番目の要素が変数横
に代入されます。
これにより配列{"部品α","10", "15"}
にマッチすることができます。
パターンδの説明
["部品δ", .. var メーカーたち, var メインのメーカー]
の ..
は任意長の部分配列を意味します。
この場合、長さが2以上の配列のうち、先頭要素が"部品δ
のものにマッチし、最後要素が変数メインのメーカー
に、その真ん中の要素が配列として変数メーカーたち
に代入されます。
これにより配列{"部品δ", "A社", "B社", "C社", "B社"}
にマッチすることができます。
パターンεの説明
読む必要のない箇所を読み飛ばすこともできます。
["部品ε", _, var 寸法, ..] => new 部品ε(int.Parse(寸法))
は、長さ3以上の配列のうち、先頭要素が "部品ε"
のものにマッチし、2番目の要素は無視し、3番目の要素を変数寸法
に代入し、4番目以降の要素たちを無視します。
これにより配列{"部品ε", "コメント数3", "10", "コメント:この部品は廃止される", "コメント2:廃止年度は2026年", "コメント3:大体部品の検討中"}
にマッチすることができます。
まとめ
C# 11 で導入されたリストパターンの使用例を紹介しました。まだ導入されて日が浅いですが、便利なパターンマッチなので使用例も今後増えてくるかなと思っています。
Discussion