使用Reflection.Emit从另一个对象获取属性值



这是我第一次尝试使用Reflection.Emit。我正在为提供的对象动态构建代理。代理将任何公共属性访问传递给所提供的对象。我收到的错误是:

对象"ProxyObject"上的属性访问器"AccessorName"抛出了以下异常:尝试使用方法'ProxyObject.get_AccessorName()'访问方法"NS.CoreObject.get_AccessorName()失败了。

根据我的假设和收集,这可能是由于自动生成的属性getter方法是私有和隐藏的。但是我如何使用MethodBuilder来解决这个问题呢?

根据帖子创建动态方法分配值给一个属性?,您可以通过声明与目标模块"关联"的方法来使用DynamicMethod,但是我需要构建一个完整的类。是否有一种等价的"关联"可以通过Reflection.Emit实现?

这是我试图执行的一个基本操作,所以我确信它是我没有意识到的直接和简单的东西。

对于MethodBuilder,您不能。您必须遵守通常的可访问性规则。然而,你可以通过DynamicMethod作弊,它允许你假装(如果你有足够的访问权限),你正在创建的方法实际上是给定类型(或给定模块等)的静态方法。这意味着可以自由访问私有状态,例如:

using System;
using System.Reflection;
using System.Reflection.Emit;
public class Foo
{
    public Foo(int bar)
    {
        Bar = bar;
    }
    private int Bar { get; set; }
}
static class Program {
    static void Main()
    {
        var method = new DynamicMethod("cheat", typeof(int),
            new[] { typeof(object) }, typeof(Foo), true);
        var il = method.GetILGenerator();
        il.Emit(OpCodes.Ldarg_0);
        il.Emit(OpCodes.Castclass, typeof(Foo));
        il.Emit(OpCodes.Callvirt, typeof(Foo).GetProperty("Bar",
            BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
            ).GetGetMethod(true));
        il.Emit(OpCodes.Ret);
        var func = (Func<object, int>)method.CreateDelegate(
            typeof(Func<object, int>));
        var obj = new Foo(123);
        Console.WriteLine(func(obj));
    }
}

如果您只获取属性的值,还应该注意Delegate.CreateDelegate可以通过getter方法自动执行相同的操作:

var method = typeof(Foo).GetProperty("Bar",
    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
    .GetGetMethod(true);
var func = (Func<Foo, int>)
    Delegate.CreateDelegate(typeof(Func<Foo, int>), method);

最新更新