本文示例源代码或素材下载
今天我们来研究下用IL书写For循环和Foreach循环,在书中一直看到说使用Foreach循环比普通的For循环来的好,这次正好趁机来看看他们的IL代码有何不同.按照惯例,我们先给出要实现的类的C#代码,如下:
class Iterator
{
public int ForMethod(int[] ints)
{
int sum = 0;
for (int i = 0; i < ints.Length; i++)
{
sum += ints[i];
}
return sum;
}
public int ForeachMethod(int[] ints)
{
int sum = 0;
foreach (int i in ints)
{
sum += i;
}
return sum;
}
}
然后,我们先来实现其中的ForMethod,相信大家已经等不及了,那么我先给出实现的IL代码,然后针对其中的关键部分进行讲解,代码如下:
MakeForMethod
/// <summary>
/// 生成For循环
/// </summary>
/// <param name="typeBuilder"></param>
static void MakeForMethod(TypeBuilder typeBuilder)
{
//定义一个传入参数为Int32[],返回值为Int32的方法
MethodBuilder methodBuilder = typeBuilder.DefineMethod("ForMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(Int32), new Type[] { typeof(Int32[]) });
ILGenerator methodIL = methodBuilder.GetILGenerator();
//用来保存求和结果的局部变量
LocalBuilder sum = methodIL.DeclareLocal(typeof(Int32));
//循环中使用的局部变量
LocalBuilder i = methodIL.DeclareLocal(typeof(Int32));
Label compareLabel = methodIL.DefineLabel();
Label enterLoopLabel = methodIL.DefineLabel();
//int sum = 0;
methodIL.Emit(OpCodes.Ldc_I4_0);
methodIL.Emit(OpCodes.Stloc_0);
//int i = 0
methodIL.Emit(OpCodes.Ldc_I4_0);
methodIL.Emit(OpCodes.Stloc_1);
methodIL.Emit(OpCodes.Br, compareLabel);
//定义一个标签,表示从下面开始进入循环体
methodIL.MarkLabel(enterLoopLabel);
//sum += ints[i];
//其中Ldelem_I4用来加载一个数组中的Int32类型的元素
methodIL.Emit(OpCodes.Ldloc_0);
methodIL.Emit(OpCodes.Ldarg_0);
methodIL.Emit(OpCodes.Ldloc_1);
methodIL.Emit(OpCodes.Ldelem_I4);
methodIL.Emit(OpCodes.Add);
methodIL.Emit(OpCodes.Stloc_0);
//i++
methodIL.Emit(OpCodes.Ldloc_1);
methodIL.Emit(OpCodes.Ldc_I4_1);
methodIL.Emit(OpCodes.Add);
methodIL.Emit(OpCodes.Stloc_1);
//定义一个标签,表示从下面开始进入循环的比较
methodIL.MarkLabel(compareLabel);
//i < ints.Length
methodIL.Emit(OpCodes.Ldloc_1);
methodIL.Emit(OpCodes.Ldarg_0);
methodIL.Emit(OpCodes.Ldlen);
methodIL.Emit(OpCodes.Conv_I4);
methodIL.Emit(OpCodes.Clt);
methodIL.Emit(OpCodes.Brtrue_S, enterLoopLabel);
//return sum;
methodIL.Emit(OpCodes.Ldloc_0);
methodIL.Emit(OpCodes.Ret);
}
版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明!