首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DynamicMethod调用实例方法

DynamicMethod调用实例方法
EN

Stack Overflow用户
提问于 2015-12-15 21:04:30
回答 1查看 1.9K关注 0票数 3

如果我在类方法中创建一个DynamicMethod,如何从DynamicMethod代理调用类的另一个方法?我需要以某种方式在DynamicMethod代码中捕获这个引用。但是,我找不到一个超限版本的ILGenerator.Emit,它以对象作为参数。

到目前为止,守则是:

代码语言:javascript
复制
    void CallOpc(string name, object[] inp, object[] outp)
    {
        //...
    }

    public D CreateDelegate<D>(string opcName) where D : class
    {
        var dType = typeof(D);
        var invoke = dType.GetMethod("Invoke");

        var parameters = invoke.GetParameters();
        var paramTypes = parameters.Select(p => p.ParameterType).ToArray();
        DynamicMethod dm = new DynamicMethod(
            opcName,
            invoke.ReturnType,
            paramTypes,
            true);

        var inp = parameters.Where(p => !p.IsOut).Select(p => p.ParameterType).ToList();
        var outp = parameters.Where(p => p.IsOut).Select(p => p.ParameterType).ToList();
        if (invoke.ReturnType != typeof(void))
        {
            outp.Insert(0, invoke.ReturnType);
        }
        ILGenerator il = dm.GetILGenerator();

        LocalBuilder invar = il.DeclareLocal(typeof(object[]));
        LocalBuilder outvar = il.DeclareLocal(typeof(object[]));

        il.Emit(OpCodes.Ldc_I4, inp.Count);
        il.Emit(OpCodes.Newarr, typeof(object));
        il.Emit(OpCodes.Stloc, invar);

        for (int i = 0; i < inp.Count; i++)
        {
            il.Emit(OpCodes.Ldloc, invar);
            il.Emit(OpCodes.Ldc_I4, i);
            int j = Array.IndexOf(paramTypes, inp[i]);
            il.Emit(OpCodes.Ldarg, j);
            if (!inp[i].IsClass)
            {
                il.Emit(OpCodes.Box, inp[i]);
            }
            il.Emit(OpCodes.Stelem_Ref);
        }

        il.Emit(OpCodes.Ldc_I4, outp.Count);
        il.Emit(OpCodes.Newarr, typeof(object));
        il.Emit(OpCodes.Stloc, outvar);

        il.Emit(OpCodes.Ldarg_0);   // <- push this on the evaluation stack ???
        il.Emit(OpCodes.Ldstr, opcName);
        il.Emit(OpCodes.Ldloc, invar);
        il.Emit(OpCodes.Ldloc, outvar);
        MethodInfo callOpcMeth = GetType().GetMethod("CallOpc", BindingFlags.Instance | BindingFlags.NonPublic);
        il.Emit(OpCodes.Callvirt, callOpcMeth);


        for (int o = 0; o < outp.Count; o++)
        {
            // TODO: handle out params and return value
        }
        il.Emit(OpCodes.Ret);
        return (D)(object)dm.CreateDelegate(dType);
    }

我的问题是这条线上标着?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-15 22:14:30

如何从this引用DynamicMethod指针?

在低级别,方法没有特定的this指针,相反,方法的第一个参数被用作this

要引用this指针,请执行以下操作:

  • 将一个新参数准备到您的参数列表中,匹配要用作this的类型
  • 在任何你想要的地方用这个参数作为this
  • 使用DynamicMethod.CreateDelegate(Type,Object)创建委托,将第一个参数绑定到对象:return (D)(object)dm.CreateDelegate(dType, this);

请注意,创建动态方法是昂贵的。如果为多个实例生成相同的DynamicMethod,则应该缓存方法本身,并使用缓存的方法创建委托,但使用不同的target参数。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34299354

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档