直接比较C#的foreach与for循环底层比较,反编译成IL代码一条一条翻译。
using System;
using System.Collections;
using System.Collections.Generic;
public class C {
List<int> list = new List<int>();
public void M() {
foreach(var i in list){
}
}
public void M2(){
for(int i = 0; i < list.Count; i++){
}
}
}
.class private auto ansi '<Module>'
{
} // end of class <Module>
.class public auto ansi beforefieldinit C
extends [System.Private.CoreLib]System.Object
{
// Fields
.field private class [System.Private.CoreLib]System.Collections.Generic.List`1<int32> list
// Methods
.method public hidebysig
instance void M () cil managed
{
// Method begins at RVA 0x2050
// Code size 53 (0x35) //代码大小53
.maxstack 1 //计算所用的栈大小1
.locals init (
[0] valuetype [System.Private.CoreLib]System.Collections.Generic.List`1/Enumerator<int32>, //声明第一个参数
[1] int32 i //声明第二个参数,类型int32,命名i
)
IL_0000: nop //无事发生
IL_0001: nop
IL_0002: ldarg.0
IL_0003: ldfld class [System.Private.CoreLib]System.Collections.Generic.List`1<int32> C::list
IL_0008: callvirt instance valuetype [System.Private.CoreLib]System.Collections.Generic.List`1/Enumerator<!0> class [System.Private.CoreLib]System.Collections.Generic.List`1<int32>::GetEnumerator()
IL_000d: stloc.0
.try
{
// sequence point: hidden
IL_000e: br.s IL_001a
// loop start (head: IL_001a)
IL_0010: ldloca.s 0
IL_0012: call instance !0 valuetype [System.Private.CoreLib]System.Collections.Generic.List`1/Enumerator<int32>::get_Current()
IL_0017: stloc.1
IL_0018: nop
IL_0019: nop
IL_001a: ldloca.s 0
IL_001c: call instance bool valuetype [System.Private.CoreLib]System.Collections.Generic.List`1/Enumerator<int32>::MoveNext()
IL_0021: brtrue.s IL_0010
// end loop
IL_0023: leave.s IL_0034
} // end .try
finally
{
// sequence point: hidden
IL_0025: ldloca.s 0
IL_0027: constrained. valuetype [System.Private.CoreLib]System.Collections.Generic.List`1/Enumerator<int32>
IL_002d: callvirt instance void [System.Private.CoreLib]System.IDisposable::Dispose()
IL_0032: nop
IL_0033: endfinally
} // end handler
IL_0034: ret
} // end of method C::M
.method public hidebysig
instance void M2 () cil managed
{
// Method begins at RVA 0x20a4
// Code size 30 (0x1e) //代码大小30
.maxstack 2 //计算栈大小设置为2
.locals init ( //有一个Record Frame(线程栈?)
[0] int32 i, //声明下标0的int32类型的参数 i
[1] bool //声明下标1的bool类型的匿名参数
)
IL_0000: nop //无事发生
IL_0001: ldc.i4.0 //声明整形,4字节,赋值0,入栈 1
IL_0002: stloc.0 //赋值给0号参数,出栈 0
// sequence point: hidden
IL_0003: br.s IL_000b 无条件跳转 IL_000b
// loop start (head: IL_000b)
IL_0005: nop //无事发生
IL_0006: nop
IL_0007: ldloc.0 //取Record Frame的0号参数,入栈 1
IL_0008: ldc.i4.1 //定义一个4字节整形并赋值1,入栈 2
IL_0009: add //相加,参数出栈0 结果入栈1
IL_000a: stloc.0 //赋值到Record Frame第0个参数,出栈 0
IL_000b: ldloc.0 ///取Record Frame的0号参数,入栈 1
IL_000c: ldarg.0 //取Record Frame的0号参数,入栈 2
IL_000d: ldfld class [System.Private.CoreLib]System.Collections.Generic.List`1<int32> C::list //加载参数0为List
IL_0012: callvirt instance int32 class [System.Private.CoreLib]System.Collections.Generic.List`1<int32>::get_Count() //计算长度,入栈2
IL_0017: clt //小于比较,命令的参数必须在调用前装入堆栈,该函数从堆栈中移除参数并把运算后的结果压入堆栈 出栈 0 入栈 1
IL_0019: stloc.1 //赋值到Record Frame第1个参数,出栈 0
// sequence point: hidden
IL_001a: ldloc.1 //1号变量 取Record Frame的1号参数,入栈 1
IL_001b: brtrue.s IL_0005 //判断栈顶是否为true,是则跳转 IL_0005 出栈 0
// end loop
IL_001d: ret
} // end of method C::M2
.method public hidebysig specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at RVA 0x20ce
// Code size 19 (0x13)
.maxstack 8
IL_0000: ldarg.0
IL_0001: newobj instance void class [System.Private.CoreLib]System.Collections.Generic.List`1<int32>::.ctor()
IL_0006: stfld class [System.Private.CoreLib]System.Collections.Generic.List`1<int32> C::list
IL_000b: ldarg.0
IL_000c: call instance void [System.Private.CoreLib]System.Object::.ctor()
IL_0011: nop
IL_0012: ret
} // end of method C::.ctor
} // end of class C