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

标签 .net reflection.emit

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

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 方法是私有(private)的和隐藏的。但是我如何使用 MethodBuilder 来解决这个问题? ?

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

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

最佳答案

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

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

关于.net - 使用 Reflection.Emit 从另一个对象获取属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13990940/

相关文章:

c# - 不带日期时间函数(如 ToShortDateString())的 DateTime 等类型的隐式运算符

.net - Rx 订阅和垃圾收集

.net - 如何为通过 Reflection.Emit 创建的类型指定命名空间?

c# - Reflection.Emit.ILGenerator异常处理 "Leave"指令

c# - 在 C# 中,null 是否也继承自 Object?

.net - 在数据库事务中自动包装单元测试?

c# - 何时以及如何使用 Ldvirtftn 操作码?

c# - 为什么在发出通过值类型泛型相互引用的类时会出现此异常?

c# - Reflection.Emit 不安全代码

c# - 使用 .NET 将 Json 转换为 List<object>