LINQの拡張メソッドとしてよく挙げれるForEach
。
標準ではIList<T>
のみに実装されているのでIEnumerable<T>
で使えるように拡張されてる方も多いのではないでしょうか?
実はそのForEach
、Select
など他のLINQのメソッドに置き換えられるかもしれません。
例えば(私が)よく見るのは以下のケース。(あまり良い例ではないけど…。)
var list = new List<int>();
var range = Enumerable.Range(0, 10).ForEach(x =>
{
list.Add(x);
});
とりあえず配列を回して動的配列(List
)に詰めるパターン。
これは以下のように書くことができます。
var list = Enumerable.Range(0, 10).ToList();
続いては以下のケース。
var list = new List<int>();
var range = Enumerable.Range(0, 10).ForEach(x =>
{
var value = x * x;
list.Add(value);
});
ForEachで回してる値を何か操作してから配列に詰めるパターン。
var list = Enumerable.Range(0, 10).Select(x => x * x).ToList();
これも上記のように書くことができます。
次は以下のようなケース。
var list = new List<int>();
var range = Enumerable.Range(0, 10).ForEach(x =>
{
if (x % 2 == 0)
list.Add(x);
});
ループで回してる値を条件によって配列に詰めるパターン。
var list = Enumerable.Range(0, 10).Where(x => x % 2 == 0).Select(x => x).ToList();
これは上記のように書くことができます。
(更に言えば上記の場合はSelect
メソッドも省略できますね。)
どういう時にForEach
でなくSelect
で出来るかというと、ループで回してる中身に戻り値があるとき、
って憶えておけばいいと思います。
あとはForEach
内でif
文があるならそれはWhere
で代用できます。
逆を言えば戻り値がないとき(void
)は通常ループのforeach
なりForEach
メソッドなり使えばいいと思います。
あとこれまでの例ではList
を使ってきましたが、Add
やRemove
とかしないのであればArray
の方がいいと思います。
下手にList
にして知らないうちでデータが足らなくなったとか多くなったとか、読み取り専用でないオブジェクトはバグの始まりだったりするので。