static void Main(string[] args)
{
string[] names = new string[] { "zhang", "li", "wang" };
foreach (string name in names)
Console.WriteLine(name);
Console.ReadKey();
}对应的MSIL代码为:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// 代码大小 80 (0x50)
.maxstack 3
.locals init ([0] string[] names,
[1] string name,
[2] string[] CS$0$0000,
[3] string[] CS$6$0001,
[4] int32 CS$7$0002,
[5] bool CS$4$0003)
IL_0000: nop
IL_0001: ldc.i4.3
IL_0002: newarr [mscorlib]System.String
IL_0007: stloc.2
IL_0008: ldloc.2
IL_0009: ldc.i4.0
IL_000a: ldstr "zhang"
IL_000f: stelem.ref
IL_0010: ldloc.2
IL_0011: ldc.i4.1
IL_0012: ldstr "li"
IL_0017: stelem.ref
IL_0018: ldloc.2
IL_0019: ldc.i4.2
IL_001a: ldstr "wang"
IL_001f: stelem.ref
IL_0020: ldloc.2
IL_0021: stloc.0
IL_0022: nop
IL_0023: ldloc.0
IL_0024: stloc.3
IL_0025: ldc.i4.0
IL_0026: stloc.s CS$7$0002
IL_0028: br.s IL_003c
IL_002a: ldloc.3
IL_002b: ldloc.s CS$7$0002
IL_002d: ldelem.ref
IL_002e: stloc.1
IL_002f: ldloc.1
IL_0030: call void [mscorlib]System.Console::WriteLine(string)
IL_0035: nop
IL_0036: ldloc.s CS$7$0002
IL_0038: ldc.i4.1
IL_0039: add
IL_003a: stloc.s CS$7$0002
IL_003c: ldloc.s CS$7$0002
IL_003e: ldloc.3
IL_003f: ldlen
IL_0040: conv.i4
IL_0041: clt
IL_0043: stloc.s CS$4$0003
IL_0045: ldloc.s CS$4$0003
IL_0047: brtrue.s IL_002a
IL_0049: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
IL_004e: pop
IL_004f: ret
} // end of method Program::Main下边我们做些简单的分析
.locals init ([0] string[] names,
[1] string name,
[2] string[] CS$0$0000,
[3] string[] CS$6$0001,
[4] int32 CS$7$0002,
[5] bool CS$4$0003)我们在C#代码中只声明了两个局部变量names和name,但在MSIL中多出了4个。
IL_0000: nop
IL_0001: ldc.i4.3
IL_0002: newarr [mscorlib]System.String
IL_0007: stloc.2
IL_0008: ldloc.2
IL_0009: ldc.i4.0
IL_000a: ldstr "zhang"
IL_000f: stelem.ref
IL_0010: ldloc.2
IL_0011: ldc.i4.1
IL_0012: ldstr "li"
IL_0017: stelem.ref
IL_0018: ldloc.2
IL_0019: ldc.i4.2
IL_001a: ldstr "wang"
IL_001f: stelem.ref
IL_0020: ldloc.2
IL_0021: stloc.0可以看到,MSIL先创建辅助字符串数组CS$0$0000,分配各元素的值,然后赋值给我们的names数组,感觉是转了一圈间接的来创建names数组,不知有什么优点?
IL_0022: nop
IL_0023: ldloc.0
IL_0024: stloc.3
IL_0025: ldc.i4.0
IL_0026: stloc.s CS$7$0002
IL_0028: br.s IL_003c
IL_002a: ldloc.3
IL_002b: ldloc.s CS$7$0002
IL_002d: ldelem.ref
IL_002e: stloc.1
IL_002f: ldloc.1
IL_0030: call void [mscorlib]System.Console::WriteLine(string)
IL_0035: nop
IL_0036: ldloc.s CS$7$0002
IL_0038: ldc.i4.1
IL_0039: add
IL_003a: stloc.s CS$7$0002
IL_003c: ldloc.s CS$7$0002
IL_003e: ldloc.3
IL_003f: ldlen
IL_0040: conv.i4
IL_0041: clt
IL_0043: stloc.s CS$4$0003
IL_0045: ldloc.s CS$4$0003
IL_0047: brtrue.s IL_002a从这段代码可以看出,foreach循环的内部其实是使用了for循环,CS$7$0002变量就相当于我们for循环中的i。让人困惑的是,这边操作的字符串数组即非CS$0$0000,也非names,又弄了个新数组CS$6$0001来用于循环,实在不解。
结论
在C#中,foreach循环的内部还是使用for循环。
评论(0)
暂无评论。