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