• DynamicMethod 定义和表示动态方法


    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Practices.Unity;
    using System.Reflection;
    using System.Reflection.Emit;
    
    namespace UnityDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
    
                //实例化DynamicMethod
                DynamicMethod md = new DynamicMethod("hello", null, new Type[] { typeof(string) }, typeof(Program).Module);
    
                //生成MSIL生成器,该生成器可用于发出动态方法的方法体
                ILGenerator il = md.GetILGenerator();
          
                //定义要执行的方法
                MethodInfo call = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
    
                //将指定的指令放到指令流上,将索引为 0 的参数加载到计算堆栈上。
                il.Emit(OpCodes.Ldarg_0);
    
                //调用由传递的方法说明符指示的方法
                il.Emit(OpCodes.Call, call);
    
                //从当前方法返回,并将返回值(如果存在)从调用方的计算堆栈推送到被调用方的计算堆栈上
                il.Emit(OpCodes.Ret);
    
                //创建一个可用于执行该方法的委托
                Action<string> writeLineDelegate = (Action<string>)md.CreateDelegate(typeof(Action<string>));
    
                writeLineDelegate("hello world");
                Console.ReadLine();
            }
        }
    }
    

    DynamicMethod类: http://msdn.microsoft.com/zh-cn/library/80h6baz2%28v=vs.80%29.aspx

    ILGenerator类:http://msdn.microsoft.com/zh-cn/library/wz52k528.aspx

    OpCodes类:http://msdn.microsoft.com/zh-cn/library/x2ebty98%28v=vs.95%29.aspx

    如何:定义和执行动态方法:http://msdn.microsoft.com/zh-cn/library/exczf7b9%28v=vs.80%29.aspx

    unity生成对象的底层实现

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Practices.Unity;
    using System.Reflection;
    using System.Reflection.Emit;
    
    namespace UnityDemo
    {
        class Program
        {
            //setExisting的方法原型是Void set_Existing(System.Object)
            private static readonly MethodInfo setExisting =
            typeof(BuilderContext).GetProperty("Existing").GetSetMethod();
    
            static void Main(string[] args)
            {
                //定义一个动态方法,方法的名字是BuildUpMyMockLogger,该方法有一个BuilderContext参数,返回值为空,创建在UnityDemo.exe模块里
                DynamicMethod buildMethod = new DynamicMethod("BuildUpMyMockLogger",typeof(void),
                    new Type[] { typeof(BuilderContext) }, typeof(Program).Module);
    
                //取得IL
                ILGenerator il = buildMethod.GetILGenerator();
    
                //获取MyMockLogger构造方法
                ConstructorInfo selectedCtor = typeof(MyMockLogger).GetConstructors()[0];
    
                //创建一个MyMockLogger新实例,并将对象引用推送到计算堆栈上
                il.Emit(OpCodes.Newobj, selectedCtor);
    
                //声明MyMockLogger的变量existingObjectLocal
                LocalBuilder existingObjectLocalMyMockLogger = il.DeclareLocal(typeof(MyMockLogger));
    
                //从计算堆栈的顶部弹出MyMockLogger并将其存储到指定索引处的局部变量列表中existingObjectLocal
                il.Emit(OpCodes.Stloc, existingObjectLocalMyMockLogger);
    
                //将索引为 0 的参数加载到计算堆栈上 BuilderContext参数
                il.Emit(OpCodes.Ldarg_0);
    
                //将指定索引处的局部变量加载到计算堆栈上,把existingObjectLocalMyMockLogger传入set_Existing(System.Object)
                il.Emit(OpCodes.Ldloc, existingObjectLocalMyMockLogger);
    
                //对对象调用后期绑定方法,并且将返回值推送到计算堆栈上
                il.EmitCall(OpCodes.Callvirt, setExisting, null);
    
                //从当前方法返回,并将返回值(如果存在)从调用方的计算堆栈推送到被调用方的计算堆栈上
                il.Emit(OpCodes.Ret);
    
                //创建一个可用于执行该方法的委托
                DynamicMethodBuildPlan p = new DynamicMethodBuildPlan((DynamicBuildPlanMethod)buildMethod.CreateDelegate(typeof(DynamicBuildPlanMethod)));
    
                BuilderContext context = new BuilderContext();
                if (context.Existing == null)
                {
                    Console.WriteLine("context.Existing == null");
                }
                //调用动态生成的方法
                p.BuildUp(context);
    
                ((MyMockLogger)context.Existing).SayHello();
    
                Console.ReadLine();
            }
        }
    
        class BuilderContext
        {
            private object m = null;
            public object Existing
            {
                get
                {
                    return m;
                }
                set
                {
                    m = value;
                }
            }
        }
    
        delegate void DynamicBuildPlanMethod(BuilderContext context);
    
        class DynamicMethodBuildPlan
        {
            private DynamicBuildPlanMethod planMethod;
    
            public DynamicMethodBuildPlan(DynamicBuildPlanMethod planMethod)
            {
                this.planMethod = planMethod;
            }
    
            public void BuildUp(BuilderContext context)
            {
                planMethod(context);
            }
        }
    
        class MyMockLogger
        {
            public MyMockLogger()
            {
                Console.WriteLine("MyMockLogger() Invoked");
            }
    
            public void SayHello()
            {
                Console.WriteLine("SayHello() in MyMockLogger");
            }
        }
    }
    
  • 相关阅读:
    点击对话框非标题栏可以移动对话框
    键盘按键的处理和单字节的判断,不允许输入汉字
    MFC 打开网页
    那些坑爹的python面试题
    jQuery上传插件uploadify
    jQuery插件之我的flexiGrid
    浏览器常见兼容点
    jQuery之右键菜单
    javascript调用函数的几种方法
    JavaScript的匿名函数和闭包【转帖】
  • 原文地址:https://www.cnblogs.com/50614090/p/2332669.html
Copyright © 2020-2023  润新知