这是我第一次尝试使用Reflection.Emit。我正在为提供的对象动态构建代理。代理将任何公共属性访问传递给提供的对象。我收到的错误是:
对象'ProxyObject'上的属性访问者'AccessorName'引发了以下异常: 尝试通过方法'ProxyObject.get_AccessorName()'来访问方法 'NS.CoreObject.get_AccessorName()失败。
从我可以假设和收集的内容来看,这可能是由于自动生成的属性getter方法是私有的和隐藏的。但是,如何使用MethodBuilder
?
根据Create DynamicMethod to assign value to a property?的帖子,您可以通过声明方法与目标模块“关联”来使用DynamicMethod来完成,但我需要构建一个完整的类。是否可以通过Reflection.Emit实现等效的“关联”?
这是我正在尝试执行的一项基本操作,因此我确信这是一些我不知道的直接和简单的事情。
答案 0 :(得分: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);