不错呦!smile@林凯西,确保“准备文件”中的几个文件都有安装,S...您好,看了您这篇帖子觉得很有帮助。但是有个问题想请...我的修改过了怎么还被恶意注册呢 @jjjjiiii 用PJ快9年了,主要是A...PJ3啊,貌似很少有人用PJ了,现在不是WP就是z...@332347365,我当时接入时错误码没有-10...楼主,ChkValue值应为-103是什么意思呢?...大哥 你最近能看到我发的信息,请跟我联系,我有个制...
通过MSIL看foreach循环
编辑:dnawo 日期:2010-05-14
复制内容到剪贴板
程序代码

static void Main(string[] args)
{
string[] names = new string[] { "zhang", "li", "wang" };
foreach (string name in names)
Console.WriteLine(name);
Console.ReadKey();
}
{
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
{
.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)
[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
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
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 | 引用: 0 | 查看次数: 3812
发表评论
请登录后再发表评论!