以下の内容は、日経BPより出版されているC#ショートコードプログラミングの補遺です。C#ショートコードプログラミングで解説している前提はここでは繰り返しません。
ある型のコレクションと同じ数の要素を持つが別の型のインスタンスで初期化したコレクションが欲しい。つまり、A型の配列からB型の配列を作りたい。
依存バージョン §
C# 3.0以降
OLD CODE §
internal static Item SelectFewItemsWithoutCancel(string p, Item[] items)
{
if (items.Length == 1) return items[0];
SimpleMenuItem[] ar = new SimpleMenuItem[items.Length];
for (int i = 0; i < items.Length; i++)
{
ar[i] = new (items[i].Name);
}
int index = UI.SimpleMenuWithoutSystem(p, ar);
return items[index];
}
NEW CODE §
internal static Item SelectFewItemsWithoutCancel(string p, Item[] items)
{
if (items.Length == 1) return items[0];
return items[UI.SimpleMenuWithoutSystem(p, items.Select(c => new SimpleMenuItem(c.Name)).ToArray())];
}
解説 §
さて、この書き換えは現在進行形です。たった今、目の前で行われた書き換えです。他人事のように書いていますが、もちろん書き換えたのは自分です。予想外の書き換えだったので紹介します。当初OLD CODEを書いたときは、「まあこんなものかな」と思っていました。これ以上無理に短くしても、可読性を落とすだけであまり意味は無いと思っていました。
ところは今はNEW CODEです。ここで以下のような感想を持った読者も多いでしょう。
- 可読性が著しく落ちていて、意味が分かりにくい。型変換だけを意図したSelectメソッドの利用などトリックに走りすぎだ
しかし、このような書き換えを行った意図は真逆なのです。
「型変換だけを意図したSelectメソッドの利用」はけして特殊な思いつきやひねくれたトリックなどではなく、既に「定番のパターンの1つ」なのです。
このメソッドは、Item型の配列を受け取り、SimpleMenuItem型の配列をメソッドに渡すことを意図しています。単に型が違うだけです。このようなケースでは、「コレクションの型変換を意図したSelectパターン」を使うと短くできることが、このパターンを知っている人なら誰でも容易に想像ができます。
つまり単なる前提知識の問題です。LINQの無い言語のプログラマには発想することが出来ないパターンだとしても、C#では既に定番のパターンの1つであり、何ら奇異なことはありません。少し1行が長いかな、という懸念があるだけです。しかし、それを真剣に受け止めるとしても文の途中に改行を入れて分けるだけで良く、文の数を増やす必要はありません。