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

.net 使用Reflection.Emit从另一个对象获取属性值,.net,reflection.emit,.net,Reflection.emit,这是我第一次尝试使用Reflection.Emit。我正在为提供的对象动态构建代理。代理将任何公共属性访问传递给提供的对象。我收到的错误是: 对象“ProxyObject”上的属性访问器“AccessorName”引发了以下异常: 通过方法“ProxyObject.get_AccessorName()”尝试访问该方法 'NS.CoreObject.get_AccessorName()失败 根据我的假设和收集,这是由于自动生成的属性getter方法是私有的和隐藏的。但是如何使用MethodBuil

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

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

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

根据上的帖子,您可以通过声明方法与目标模块“关联”来使用DynamicMethod,但我需要构建一个完整的类。是否有一个等效的“关联”可以通过反射来实现。发射


这是我试图执行的一个基本操作,因此我确信这是一个我不知道的简单明了的操作。

使用
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));
    }
}

有道理(也很有创意)。如果我正在通过TypeBuilder构建一个类型,我是否能够将您的答案生成的IL转换为TypeBuilder构建的类型?或者这两个是相互排斥的?@redman得到相同的IL也无济于事。TypeBuilder仍然局限于标准的可访问性。在IL级别,你可以要求任何东西:在第一次使用时仍然会被检查。我刚刚意识到我的部分问题是模棱两可的。我试图访问的属性是公共的。不是自动生成的访问者。(我更新了我的问题以反映这一点。)考虑到这一点,通过MethodBuilder使用另一个对象的属性是否更容易?虽然答案没有回答我的预期问题,但它回答了基于模糊框架的感知问题。为此,你必须获得荣誉。现在我至少知道了一个将来使用的技巧。@redman如果属性访问器是公共的,它应该可以正常工作,这就是MethodAccessException。听起来这家酒店实际上并不是公共的。首先,你从中得到的IL在你的emit代码中也会非常有用。当然,当你的类不是公共的时候,公共属性就没有任何意义了。在我看来,这种类型是在同一个模块中定义的。又一个“我在这上面浪费了几个小时?”的时刻。
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);