C#7で追加されたタプルのフィールドを分解する構文について、タプル専用の機能ではなくユーザ定義の型でも分解が行えると知ったので試してみました。
タプルのフィールドを分解する構文は以下のようになります。
var t = (Value1: 2, Value2: 3D);
var(v1, v2) = t;
1行目で2つのフィールドを保持するタプル変数tを作成し、
2行目で変数tのフィールドをv1とv2に分解しています。
これだけでは意味が無いですが、メソッドの戻り値はタプルで返し、
メソッド実行側はすぐに分解して使用したい場合などに役立ちます。
上記の分解と同様のことを行うには、クラスや構造体にDeconstructメソッドを実装します。拡張メソッドでもOKです。
KeyValuePair構造体のDeconstruct拡張メソッド実装例は以下のようになります。
public static void Deconstruct<TKey, TValue>(this KeyValuePair<TKey, TValue> pair, out TKey key, out TValue value) {
key = pair.Key;
value = pair.Value;
}
例えば、Dictionaryの各要素をforeachで処理する場合、今まであれば以下のようになります。
var dic = new Dictionary<string, int>();
foreach (var pair in dic) {
Console.WriteLine(pair.Key + "=" + pair.Value);
}
Deconstruct拡張メソッドを実装して分解が行えるようになると、以下のような実装が可能になります。
var dic = new Dictionary<string, int>();
foreach (var (name, score) in dic) {
Console.WriteLine(name + "=" + score);
}
変数pairを使用する必要がなくなり、pair.Keyとpair.Valueではなく、本来のフィールドの意味を表す変数名を名付けて利用できるようになりました。