.NET如何查看源程序的IL(中间语言)代码

在开发.NET过程中,如果遇到对代码执行结果有异议时,在现有代码的基础上不能找到问题,如何透过事物看本质,这就需要从编译器底层找问题,这时候IL(中间语言)就是必备的基础了。.

IL简介

首先了解一下什么是“中间语言”(简称 IL)?IL的全称是Intermediate Language (IL)即将.NET代码转化为机器语言的一个中间语言的缩写, 中间语言是编译使用高级 .NET 语言编写的代码后获得的结果。我们可以把他理解为为汇编。 对使用其中一种语言编写的代码进行编译后,即可获得 IL 所生成的二进制代码。

ILDasm工具的使用方法

IL中间语言查看工具有ILSpy和ILDasm等等,ILDasm是微软官方出品的查看中间语言的工具。ILSpy是开源项目,在.NET framework时代可以查看中间语言过程,但是后来的.NET Core之后由于新的机制就不能查看,只能反编译代码,大家可以试一试。接下来看看ILDasm如何使用。

使用方法有两种,第一添加到Visual Studio的工具里,然后直接打开ILDasm使用就可以了;第二种是在Visual Studio命令提示框输入ildasm打开。下面来简单介绍一下。

1)加到Visual Studio的工具里

打开Visual Studio工具,点击“添加”添加一个工具,点击“命令”后面的打开文件位置找到ILDasm所在目录点击选中ildasm.exe文件后点击确定就可以添加成功(图1-1),使用方法直接在工具里打开(图1-2)。

添加的位置一般在:

C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools文件夹下的。

.NET如何查看源程序的IL(中间语言)代码

.NET如何查看源程序的IL(中间语言)代码

2)Visual Studio命令提示打开

这个比较简单,打开Visual Studio命令提示窗口,输入ildasm点击回车即可打开(如图2-1)

.NET如何查看源程序的IL(中间语言)代码

二种方法各有优点,根据自己的使用情况来选择打开方法。

ILDasm工具的反编译说明

1)使用方法点击"文件"打开生成好的dll文件,如果是.NET framework版本可以打开.EXE文件查看中间语言。如图2-2

.NET如何查看源程序的IL(中间语言)代码

2)打开文件中的符号代表(图2-3):

.NET如何查看源程序的IL(中间语言)代码

3)双击打开MANIFEST,这是程序的清单文件。红色箭头表示引用的外部类库是System.Runtime,如图:

.NET如何查看源程序的IL(中间语言)代码

4)查看main方法:

依次展开Program,双击带有mian的图标,如下图:

.NET如何查看源程序的IL(中间语言)代码

5)查看foreach遍历数组的反编译

听说.net如果用foreach遍历数组,在中间语言会转换成for循环。我们来看看反编译的代码。这里新建了一个数组,分别用for和foreach循环,再新建个List<int>,用foreach遍历,代码如下:

int[] vtest = new int[5] { 1, 2, 3, 4, 5 };
            for (int i = 0; i < vtest.Length; i++)
            {
                Console.WriteLine(vtest[i]);
            }
            foreach (var item in vtest)
            {
                Console.WriteLine(item);
            }

           List<int> list= new List<int>();
            list.Add(1);
            list.Add(2);
            list.Add(3);
            list.Add(4);
            list.Add(5);
            foreach (var item in list)
            {
                Console.WriteLine(item);
            }

生成成功后我们看反编译的结果:

下图新建数组的中间语言,长这样,我们先略过

.NET如何查看源程序的IL(中间语言)代码

先看下图list<int>数组添加和遍历,大家看看是否有"Enumerator<int32>::MoveNext()",这是foreach遍历的源码,如果看过.net 源码的很熟悉吧!

.NET如何查看源程序的IL(中间语言)代码

在来看看遍历素组的foreach,如下图,没有发现有Enumerator<int32>::MoveNext()的字眼吧,说明foreach执行循环未遍历。

.NET如何查看源程序的IL(中间语言)代码

由于篇幅有限,不再做过多说明,感兴趣大家可以自己试一试。

结语

水平有限,如果你有更好的想法和建议,欢迎留言讨论。