C# for vs. foreach Over An Array
This article coincides with this weblog entry and is intended to show the compiler differences between enumerating the elements in an Array using a manual for loop vs. using a foreach loop.
for approach
<codeSnippet language="C#">MyStruct[] myStructs = new MyStruct[3];
for(int index = 0; index < myStructs.Length; index++){
Console.WriteLine("{0}", myStructs[index].MyField);
}
</codeSnippet>
<codeSnippet language="CIL">
.method public hidebysig instance void Test1() cil managed
{
// Code size 55 (0x37)
.maxstack 4
.locals init (valuetype Test.Class1/MyStruct[] V_0,
int32 V_1)
IL_0000: ldc.i4.3
IL_0001: newarr Test.Class1/MyStruct
IL_0006: stloc.0
IL_0007: ldc.i4.0
IL_0008: stloc.1
IL_0009: br.s IL_0030
IL_000b: ldstr "value of MyField for MyStruct at {0} is {1}"
IL_0010: ldloc.1
IL_0011: box [mscorlib]System.Int32
IL_0016: ldloc.0
IL_0017: ldloc.1
IL_0018: ldelema Test.Class1/MyStruct
IL_001d: ldfld int32 Test.Class1/MyStruct::MyField
IL_0022: box [mscorlib]System.Int32
IL_0027: call void [mscorlib]System.Console::WriteLine(string,
object,
object)
IL_002c: ldloc.1
IL_002d: ldc.i4.1
IL_002e: add
IL_002f: stloc.1
IL_0030: ldloc.1
IL_0031: ldloc.0
IL_0032: ldlen
IL_0033: conv.i4
IL_0034: blt.s IL_000b
IL_0036: ret
} // end of method Class1::Test1
</codeSnippet>
foreach approach
<codeSnippet language="C#">MyStruct[] myStructs = new MyStruct[3];
foreach(MyStruct aStruct in myStructs)
{Console.WriteLine("{0}", aStruct.MyField);
}</codeSnippet>
<codeSnippet language="CIL">
.method public hidebysig instance void Test2() cil managed
{
// Code size 59 (0x3b)
.maxstack 2
.locals init (valuetype Test.Class1/MyStruct[] V_0,
valuetype Test.Class1/MyStruct V_1,
valuetype Test.Class1/MyStruct[] V_2,
int32 V_3)
IL_0000: ldc.i4.3
IL_0001: newarr Test.Class1/MyStruct
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: stloc.2
IL_0009: ldc.i4.0
IL_000a: stloc.3
IL_000b: br.s IL_0034
IL_000d: ldloc.2
IL_000e: ldloc.3
IL_000f: ldelema Test.Class1/MyStruct
IL_0014: ldobj Test.Class1/MyStruct
IL_0019: stloc.1
IL_001a: ldstr "{1}"
IL_001f: ldloca.s V_1
IL_0021: ldfld int32 Test.Class1/MyStruct::MyField
IL_0026: box [mscorlib]System.Int32
IL_002b: call void [mscorlib]System.Console::WriteLine(string,
object)
IL_0030: ldloc.3
IL_0031: ldc.i4.1
IL_0032: add
IL_0033: stloc.3
IL_0034: ldloc.3
IL_0035: ldloc.2
IL_0036: ldlen
IL_0037: conv.i4
IL_0038: blt.s IL_000d
IL_003a: ret
} // end of method Class1::Test2
</codeSnippet>