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

2023-09-04 02:45:14 作者:我媳妇谁敢动

这是我第一次涉足使用Reflection.Emit的。我动态生成的提供对象的代理。代理通过任何公开属性通过访问提供的对象。我收到的错误是:

This is my first foray into using Reflection.Emit. I'm dynamically building a proxy for a provided object. The proxy passes any public property accesses through to the provided object. The error I'm receiving is:

对象属性访问器AccessorName'ProxyObject抛出以下异常:   试图通过法ProxyObject.get_AccessorName()访问方法   NS.CoreObject.get_AccessorName()失败。

Property accessor 'AccessorName' on object 'ProxyObject' threw the following exception: Attempt by method 'ProxyObject.get_AccessorName()' to access method 'NS.CoreObject.get_AccessorName() failed.

从我可以承担和收集,这将是由于自动生成的属性的getter方法​​是私人和隐藏。但是,我怎么解决这个使用 MethodBuilder

From what I can assume and gather, this would be due to the automatically-generated property getter method being private and hidden. But how do I work around this using a MethodBuilder?

据该岗位在Create DynamicMethod的宣布将与目标模块相关的方法来分配的价值属性?,您可以用DynamicMethod的做到这一点,但我需要建立一个完整的类。是否有一个相当于协会,可以通过Reflection.Emit的实现?

According to the post at Create DynamicMethod to assign value to a property?, you can do it with a DynamicMethod by declaring the method to be "associated" with the target module, but I need to build a full class. Is there an equivalent "association" that can be achieved through Reflection.Emit?

这是一个基本的操作我想演出,所以我敢肯定,它的东西直截了当,简单的说,我不知道。

This is a basic operation I'm trying to perform, so I'm certain that it's something straight-forward and simple that I'm unaware of.

推荐答案

通过 MethodBuilder :你不能。你是受访问的一般规则。你可以,但是,通过 DynamicMethod的欺骗,它允许您pretend(如果你有足够的访问),您所创建的方法实际上是一个静态方法的。这意味着你的可以的自由访问私有状态,例如:

With MethodBuilder: you cannot. You are subject to the usual rules of accessibility. You can, however, cheat via DynamicMethod, which allows you to pretend (if you have enough access) that the method you are creating is actually a static method of a given type (or a given module, etc). This means you can freely access private state, for example:

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方法​​:

If you are only obtaining the value of the property, it should also be noted that Delegate.CreateDelegate can do the same automatically, via the getter method:

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);