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:
Property accessor 'AccessorName' on object 'ProxyObject' threw the following exception: Attempt by method 'ProxyObject.get_AccessorName()' to access method 'NS.CoreObject.get_AccessorName() failed.
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
?
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.
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));
}
}
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With