👥
【C#】GroupByのキーに型を付けたい
概要
C#のGroupByでキー指定をする際、record型を使用すると便利だよという話です。
※record型はC#9からの機能です。
よくある例
GroupByの複数キーを指定する場合、よく出てくる例が匿名型を使用する例です。
new { x.支店, x.役職 }
の部分で匿名型を使用しています。
// 社員リストを支店と役職でグループ化する
var groupList = 社員リスト.GroupBy(
x => new { x.支店, x.役職 });
recordを使用した例
record型を使用して複数キーを指定する例です。
new 社員グループキー(x.支店, x.役職)
の部分でrecord型を使用しています。
// 社員リストを支店と役職でグループ化する
var groupList = 社員リスト.GroupBy(
x => new 社員グループキー(x.支店, x.役職));
record 社員グループキー(支店 支店, string 役職);
匿名型だと何が不便か
匿名型を使用するとシンプルに書けて便利ですが、型情報を別メソッドに伝えることができません。
例えば次のコードのようにキーを別メソッドに渡して処理したい場合、パラメータがdynamic型となるため、メソッド内で型チェックが効きません。
// dynamicで渡すと型チェックされず実行時エラーになる
// does not contain a definition for '存在しないプロパティ'が発生
var key処理 = (dynamic key)
=> Console.WriteLine($"{key.存在しないプロパティ}");
// 社員リストを支店と役職でグループ化する
var groupList = 社員リスト.GroupBy(
x => new { x.支店, x.役職 });
foreach (var grp in groupList)
{
// キーに対して処理をしたい
key処理(grp.Key);
}
一方でrecord型を使用するとパラメータに型指定できるため、コンパイルエラーとなってくれます。型安全に開発ができるのでおすすめです。
// 型チェックされるため、ここでコンパイルエラーとなる
var key処理 = (社員グループキー key)
=> Console.WriteLine($"{key.存在しないプロパティ}");
// 社員リストを支店と役職でグループ化する
var groupList = 社員リスト.GroupBy(
x => new 社員グループキー(x.支店, x.役職));
foreach (var grp in groupList)
{
// キーに対して処理をしたい
key処理(grp.Key);
}
record 社員グループキー(支店 支店, string 役職);
まとめ
GroupByキーにrecordを使用する例をあまり見なかったので、情報共有でした。
コードも短く、型安全になるので参考にしてみてください。
以下今回使用した全コードを掲載しておきます。
var 社員リスト = new List<社員>
{
new 社員(支店.東京, "課長", "一郎"),
new 社員(支店.東京, "社員", "次郎"),
new 社員(支店.東京, "課長", "三郎"),
new 社員(支店.大阪, "社員", "四郎"),
new 社員(支店.大阪, "課長", "五郎"),
new 社員(支店.大阪, "社員", "六郎"),
};
var item処理 = (社員 item)
=> Console.WriteLine(item);
var key処理 = (社員グループキー key)
=> Console.WriteLine(key);
// 社員リストを支店と役職でグループ化する
var groupList = 社員リスト.GroupBy(
x => new 社員グループキー(x.支店, x.役職));
foreach (var grp in groupList)
{
// キーに対して処理をしたい
key処理(grp.Key);
foreach (var item in grp)
{
// itemに対して処理をしたい
item処理(item);
}
}
record 社員グループキー(支店 支店, string 役職);
record 社員(支店 支店, string 役職, string 社員名);
enum 支店 { 東京, 大阪, }
実行結果
社員グループキー { 支店 = 東京, 役職 = 課長 }
社員 { 支店 = 東京, 役職 = 課長, 社員名 = 一郎 }
社員 { 支店 = 東京, 役職 = 課長, 社員名 = 三郎 }
社員グループキー { 支店 = 東京, 役職 = 社員 }
社員 { 支店 = 東京, 役職 = 社員, 社員名 = 次郎 }
社員グループキー { 支店 = 大阪, 役職 = 社員 }
社員 { 支店 = 大阪, 役職 = 社員, 社員名 = 四郎 }
社員 { 支店 = 大阪, 役職 = 社員, 社員名 = 六郎 }
社員グループキー { 支店 = 大阪, 役職 = 課長 }
社員 { 支店 = 大阪, 役職 = 課長, 社員名 = 五郎 }
Discussion