10

私は構造体の配列を持っています。foreach配列を反復処理するときに、演算子は各要素のコピーを作成しますか? 私が理解している限りforeach、フードの下の構文糖衣は に変換されていforます。答えはノーのようですが、確認したいと思います。

PS: 誰かがすでにそれを尋ねているはずですが、簡単に見つけることができません。したがって、提供された参照を使用して重複として投票してください。

4

1 に答える 1

8

はい、値型インスタンスのコピーが作成されます。配列を反復処理する場合、foreach実際には列挙子を使用する代わりに配列アクセスを使用しますが、各配列スロットの値は引き続きコピーされます。

このコード:

struct AStruct
{
    public string a;
    public int b;

    static void Main()
    {
        var structs = new AStruct[10];

        foreach (var x in structs) {
            Console.WriteLine(x);
        }
    }
}

Main()メソッドに対して次の IL を生成します。

.method private static hidebysig
       default void Main ()  cil managed
{
    .entrypoint
    .maxstack 4
    .locals init (
            valuetype AStruct[]     V_0,
            valuetype AStruct[]     V_1,
            int32   V_2,
            valuetype AStruct       V_3)
    IL_0000:  ldc.i4.s 0x0a
    IL_0002:  newarr AStruct
    IL_0007:  stloc.0
    IL_0008:  ldloc.0
    IL_0009:  stloc.1
    IL_000a:  ldc.i4.0
    IL_000b:  stloc.2
    IL_000c:  br IL_002d

    IL_0011:  ldloc.1
    IL_0012:  ldloc.2
    IL_0013:  ldelema AStruct
    IL_0018:  ldobj AStruct
    IL_001d:  stloc.3
    IL_001e:  ldloc.3
    IL_001f:  box AStruct
    IL_0024:  call void class [mscorlib]System.Console::WriteLine(object)
    IL_0029:  ldloc.2
    IL_002a:  ldc.i4.1
    IL_002b:  add
    IL_002c:  stloc.2
    IL_002d:  ldloc.2
    IL_002e:  ldloc.1
    IL_002f:  ldlen
    IL_0030:  conv.i4
    IL_0031:  blt IL_0011

    IL_0036:  ret
} // end of method AStruct::Main

IL_0013 から IL_001d までの命令に注意してください。各配列スロットの値全体がスタックにプッシュされ、ローカル V_3 (x反復変数) に格納されます。

于 2013-01-18T21:48:20.090 に答える