C#

C#のforeachの仕組み(2) forとの比較コード

More than 1 year has passed since last update.

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) 言語仕様の確認のコメントで教えてもらった辺りから、調べてみます。

参考文献

ループ処理の大まかな歴史