5

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

对象“ProxyObject”上的属性访问器“AccessorName”引发以下异常:尝试通过方法“ProxyObject.get_AccessorName()”访问方法“NS.CoreObject.get_AccessorName() 失败。

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

根据Create DynamicMethod 的帖子为属性赋值?,您可以通过将方法声明为与目标模块“关联”来使用 DynamicMethod 来做到这一点,但我需要构建一个完整的类。是否存在可以通过 Reflection.Emit 实现的等效“关联”?

这是我正在尝试执行的一项基本操作,所以我确信这是我不知道的简单直接的操作。

4

1 回答 1

9

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);
于 2012-12-21T13:29:19.577 回答