C#のforeachの仕組み(1) 言語仕様の確認の続きです。
概要
Niigata.NET 3.0に参加して、forと比較して、foreachをブラックボックスに感じたので、少し整理したい。という話です。
Niigata.NET 3.0に参加してきました
forとforeachの比較コード
コードを書いて、モヤモヤしているところを明確にします。
まず、モヤモヤしないコード。
static void Main()
{
int[] numbers = { 0, 1, 2, 3, 4, 5, 6 };
Console.WriteLine("All loop by for");
for (int i = 0; i < numbers.Length; i++)
{
Console.WriteLine(numbers[i]);
}
Console.WriteLine("All loop by foreach");
foreach (var n in numbers)
{
Console.WriteLine(n);
}
}
モヤモヤしない実行結果。
All loop by for
0
1
2
3
4
5
6
All loop by foreach
0
1
2
3
4
5
6
次に、モヤモヤするコード。
static void Main()
{
int[] numbers = { 0, 1, 2, 3, 4, 5, 6 };
Console.WriteLine("Select loop by for");
for (int i = 1; i < numbers.Length - 1; i += 2)
{
Console.WriteLine(numbers[i]);
}
Console.WriteLine("Select loop by foreach");
// モヤモヤしているところ
foreach (var n in numbers)
{
Console.WriteLine("Oops!");
}
}
そしてモヤモヤする結果。
Select loop by Linq
1
3
5
Select loop by foreach
Oops!
Oops!
Oops!
Oops!
Oops!
Oops!
Oops!
Linqを使えば、ほぼ、同じことはできます。
しかし、増分を制御するというよりは、
奇数の集合に対して、ループしてる
感じがして、これもモヤモヤします。
static void Main()
{
int[] numbers = { 0, 1, 2, 3, 4, 5, 6 };
Console.WriteLine("Select loop by Linq");
foreach (var n in numbers.Where((n, i) => i % 2 == 1))
{
Console.WriteLine(n);
}
}
結果。
Select loop by Linq
1
3
5
まとめ
Class Arrayを継承して、振る舞いに介入できる?と
考えたのですが、『特殊クラス'Array'から派生する
ことはできません。』と、怒られました。
foreachの仕組みを理解すれば、開始位置と増分と
終了条件を指定して、ループできるのでしょうか?
そもそも、思想というか用途が違う気もしてきました。
前回、C#のforeachの仕組み(1) 言語仕様の確認のコメントで教えてもらった辺りから、調べてみます。