创建DynamicMethod为属性分配值? [英] Create DynamicMethod to assign value to a property?

查看:58
本文介绍了创建DynamicMethod为属性分配值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一项学习练习。我创建了一个使用Foo和字符串并设置A属性的方法。我使用了Reflector反汇编使以下代码发出。反汇编如下所示:

This is a learning exercise. I created a method that takes a Foo and a string and sets the A property. I used the Reflector disassembly to make the following emit code. The disassembly looks like this:

.method private hidebysig static void Spork(class ConsoleTesting.Foo f, string 'value') cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: ldarg.1 
    L_0002: callvirt instance void ConsoleTesting.Foo::set_A(string)
    L_0007: ret 
}

确定,所以我在此之后对发射代码进行了建模:

Ok, so I modeled my emit code after that:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;


namespace ConsoleTesting
{
    class Foo
    {
        public string A { get; set; }
    }

    class Program
    {
        static Action<Foo, string> GenMethodAssignment(string propName)
        {
            MethodInfo setMethod = typeof(Foo).GetMethod("get_" + propName);
            if (setMethod == null)
                throw new InvalidOperationException("no property setter available");

            Type[] argTypes = new Type[] { typeof(Foo), typeof(String) };
            DynamicMethod method = new DynamicMethod("__dynamicMethod_Set_" + propName, null, argTypes, typeof(Program));
            ILGenerator IL = method.GetILGenerator();
            IL.Emit(OpCodes.Ldarg_0);
            IL.Emit(OpCodes.Ldarg_1);
            IL.Emit(OpCodes.Callvirt, setMethod);
            IL.Emit(OpCodes.Ret);
            method.DefineParameter(1, ParameterAttributes.In, "instance");
            method.DefineParameter(2, ParameterAttributes.In, "value");

            Action<Foo, string> retval = (Action<Foo, string>)method.CreateDelegate(typeof(Action<Foo, string>));
            return retval;
        }

        static void Main(string[] args)
        {
            Foo f = new Foo();
            var meth = GenMethodAssignment("A");
            meth(f, "jason");
            Console.ReadLine();
        }
    }

我收到此异常:

JIT Compiler encountered an internal limitation.

这是什么意思,我该如何解决?

What the krunk does that mean, and how do I fix it?

编辑:

我想也许是因为目标方法是私有的,但我不确定。从 DynamicMethod MSDN页面

I thought maybe it's because the target method is private, but I'm not so sure. From the DynamicMethod MSDN page:


下面的代码示例创建一个在逻辑上与类型相关联的DynamicMethod。该关联使它可以访问该类型的私有成员。

The following code example creates a DynamicMethod that is logically associated with a type. This association gives it access to the private members of that type.


推荐答案

好吧,我知道了出来。更改

Well I figured it out. Changing

IL.Emit(OpCodes.Callvirt, setMethod);

IL.Emit(OpCodes.Call, setMethod);

修复了该问题。我不知道为什么反汇编显示CallVirt,但是。

fixed it. I don't know why the disassembly showed CallVirt, but eh.

这篇关于创建DynamicMethod为属性分配值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆