这是我第一次尝试使用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);