//对实现了迭代接口的操作类进行遍历 public static ELoop Foreach(IIterator instance, Action <Action> action) { //获取迭代需要的属性等 instance.Initialize(); ELoop loopHandler = new ELoop(); ILGenerator CurrentIL = loopHandler.il; Label lb_while_end = CurrentIL.DefineLabel(); Label lb_while_start = CurrentIL.DefineLabel(); CurrentIL.MarkLabel(lb_while_start); //设置标签位置-循环开始 CurrentIL.Emit(OpCodes.Ldloca, instance.TempEnumerator); //加载由结构体构成的迭代对象 CurrentIL.Emit(OpCodes.Call, instance.MoveNext); //调用movenext方法 CurrentIL.Emit(OpCodes.Brfalse_S, lb_while_end); //如果为false跳转到结束标签 Action loadCurrentElemenet = () => { //loadCurrentElemenet用来加载当前元素 instance.LoadCurrentElement(null); //执行实现了迭代接口的方法,通常这个方法是为了加载当前元素 }; if (action != null) { action(loadCurrentElemenet); //执行主要逻辑 } CurrentIL.Emit(OpCodes.Br_S, lb_while_start); //无条件跳转开始标签 CurrentIL.MarkLabel(lb_while_end); //设置标签位置-循环结束 CurrentIL.Emit(OpCodes.Ldloca, instance.TempEnumerator); //调用dispose方法 CurrentIL.Emit(OpCodes.Call, instance.Dispose); return(loopHandler); }
//对实现了迭代接口的操作类进行遍历 public static ELoop For(int start, int end, int increment, IIterator instance, Action <Action> action = null) { ELoop loopHandler = new ELoop(); ILGenerator CurrentIL = loopHandler.il; Label lb_while = CurrentIL.DefineLabel(); loopHandler.CurrentFlag = CurrentIL.DeclareLocal(typeof(int)); start -= 1; //为了减少标签使用,全部减少1 end -= 1; CurrentIL.Emit(OpCodes.Ldc_I4, start); //此处可优化 255一下用Ldc_I4_S 短格式 CurrentIL.Emit(OpCodes.Stloc, loopHandler.CurrentFlag); //起始值入临时变量 CurrentIL.MarkLabel(lb_while); //设置循环标签 CurrentIL.Emit(OpCodes.Ldloc, loopHandler.CurrentFlag); //其实值加increment CurrentIL.Emit(OpCodes.Ldc_I4, increment); CurrentIL.Emit(OpCodes.Add); CurrentIL.Emit(OpCodes.Stloc, loopHandler.CurrentFlag); //填充到临时变量 //生成委托,委托参数为当前起始值 Action loadCurrentElemenet = () => { //loadCurrentElemenet用来加载当前元素 instance.LoadCurrentElement(loopHandler.CurrentFlag); //迭代接口的实现 }; if (action != null) { action(loadCurrentElemenet); //主要逻辑 } CurrentIL.Emit(OpCodes.Ldloc, loopHandler.CurrentFlag); //比较并循环 CurrentIL.Emit(OpCodes.Ldc_I4, end); CurrentIL.Emit(OpCodes.Blt_S, lb_while); return(loopHandler); }