首页/技术分享

二次开发教程:Emit 循环

发布于:2019-07-24 16:35:03
3341人 分享

目的是用Emit 生成一个和TargetMethod(代码如下) 一样的方法


实现


    class Program

    {

        static void Main(string[] args)

        {

 

            var method = GetTargetMethod();

            method();

 

            Console.ReadLine();

        }

 

        static void TargetMethod()

        {

            for (int i = 0; i < 10; i++)

            {

                Console.WriteLine(i);

            }

        }

 

        static Action GetTargetMethod()

        {

            DynamicMethod dynamicMethod = new DynamicMethod("test", null, null);

            var iLGenerator = dynamicMethod.GetILGenerator();

            iLGenerator.DeclareLocal(typeof(int));//ldloc.0 表示i

            iLGenerator.DeclareLocal(typeof(bool));//ldloc.1 表示i和10 比较的结果

 

            var IL_0012 = iLGenerator.DefineLabel();

            var IL_0005 = iLGenerator.DefineLabel();

 

            var writeLine = GetWriteLine();

 

            iLGenerator.Emit(OpCodes.Nop);

            iLGenerator.Emit(OpCodes.Ldc_I4_0);//0

            iLGenerator.Emit(OpCodes.Stloc_0);//将 ldloc.0: i 设置为0

 

            iLGenerator.Emit(OpCodes.Br_S, IL_0012);//跳转到Label IL_0012

 

            iLGenerator.MarkLabel(IL_0005);//添加标签 IL_0005

            iLGenerator.Emit(OpCodes.Nop);

 

            iLGenerator.Emit(OpCodes.Ldloc_0);//将 ldloc.0: i 放入计算堆栈

            iLGenerator.Emit(OpCodes.Call, writeLine);//调用Console.WriteLine 

            iLGenerator.Emit(OpCodes.Nop);

 

            iLGenerator.Emit(OpCodes.Ldloc_0);// 将 ldloc.0: i 放入计算堆栈

            iLGenerator.Emit(OpCodes.Ldc_I4_1);//  将 1 放入计算堆栈

            iLGenerator.Emit(OpCodes.Add); // 加法

            iLGenerator.Emit(OpCodes.Stloc_0);// 将计算后的值赋值给ldloc.0: i

 

            iLGenerator.MarkLabel(IL_0012);//添加标签 IL_0012

            iLGenerator.Emit(OpCodes.Ldloc_0);// 

            iLGenerator.Emit(OpCodes.Ldc_I4_S, 10);// 将 10 放入计算堆栈

            iLGenerator.Emit(OpCodes.Clt);// 计算 i<10;

            iLGenerator.Emit(OpCodes.Stloc_1); // 将i<10 的计算结果赋值给 ldloc.1

            iLGenerator.Emit(OpCodes.Ldloc_1); // 将ldloc.1 放入计算堆栈

 

            iLGenerator.Emit(OpCodes.Brtrue_S, IL_0005);// 如果 ldloc.1 则跳转到IL_0005

 

            iLGenerator.Emit(OpCodes.Ret); // return

 

            return (Action)dynamicMethod.CreateDelegate(typeof(Action));

        }

        private static MethodInfo GetWriteLine()

        {

            Type type = typeof(Console);

            MethodInfo method = type.GetMethod("WriteLine", new Type[] { typeof(int) });

            return method;

        }

    }

转载请注明来源本文地址:https://www.tuituisoft/blog/3172.html

上一篇:

二次开发教程:orm 里使用Emit

下一篇:

二次开发教程:Emit DynamicMethod