Does foreach convert every element if it is an array of structures?

I have an array of structures. Does the foreach create a copy of each element when iterating over an array? As far as I understand, foreach is just syntactic sugar under the hood, converted to for . Thus, it seems that the answer is no, but I would like to receive confirmation.

PS: it seems someone should have already asked about this, but I can’t easily find anything. Therefore, please vote for the duplicate with the link provided.

+7
source share
1 answer

Yes, copies of the value type will be made. When iterating over an array, foreach will actually use array calls instead of using a counter, but the value in each slot in the array is still copied.

This code:

 struct AStruct { public string a; public int b; static void Main() { var structs = new AStruct[10]; foreach (var x in structs) { Console.WriteLine(x); } } } 

Creates the following IL for the Main() method:

 .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 

Pay attention to the instructions IL_0013 to IL_001d. The entire value in each slot in the array is pushed onto the stack and stored in local V_3 (iteration variable x ).

+8
source

All Articles