atsukanrockのブログ

Microsoft系技術を中心にぼちぼち更新します

foreachのinの右側の評価回数

C#のforeachステートメントでは、inの右側は一度評価されるだけである。従って、パフォーマンスを意識していったんローカル変数に格納するようなコードは書かなくてよさそう。

例えば以下のようなコードがあるとする。

public class Hoge
{
    private readonly int[] numbers = new int[] { 1, 2, 3, 4, 5, };
    public int[] Numbers
    {
        get { return (int[])numbers.Clone(); }
    }

    // 出力:1<改行>2<改行>3<改行>4<改行>5<改行>
    public void Foo()
    {
        foreach (int number in Numbers)
        {
            Console.WriteLine(number.ToString());
        }
    }
}

Fooメソッド内のforeachステートメントでは、Numbersプロパティの戻り値をinの右側に置いているが、Numbersプロパティのgetterが呼び出されるのは一度だけである。従って、numbersフィールドに対しCloneメソッドが呼び出されるのも一度だけである。

CLRは、foreachステートメントのinの右側の式を一度だけ実行し、内部的にその値を保持しているものと思われる。ただし、言語仕様を読んだわけではなく、実験して得た結論であることに注意。

ちなみにVB.NETだと、ドキュメントに明記されている。