I get the pointer of a method with the following:
public unsafe static long* GetPointer(MethodInfo info)
{
// Simplified method without any checks
// if(IntPtr.Size == 4){ return (int*)info.MethodHandle.Value.ToPointer() + 2; }
return (long*)info.MethodHandle.Value.ToPointer() + 1;
}
Func<string, int> func = x => 102;
var pointer = GetPointer(func.Method); // Works
But if I want the pointer of a generated method from a lambda expression with expression.Compile() like the following snippet, I get the following error:
The requested operation is invalid for DynamicMethod
Expression<Func<string, int>> expression = x => 102;
Func<string, int> func2 = expression.Compile();
var pointer = GetPointer(func2.Method); // Fails
If I debug GetPointer
, I get the following information for the MethodHandle
-attribute:
MethodHandle = '((System.Reflection.Emit.DynamicMethod.RTDynamicMethod)info).MethodHandle' threw an exception of type 'System.InvalidOperationException'
Does anyone know how to get the pointer of a generated method? In the end, I want to replace the body of a method with the body of another method. The method to replace the body is adopted from the SO answer here.
Update
Well, what I try to archive is for example to override the result of DateTime.Now
. In this case, my method first tries to get the setter method for the property. But DateTime.Now
has no setter, so it tries next to override the backing field. But DateTime.Now
has no backing field to override, so I want to override the getter method of DateTime.Now
. I need the expression
in the first tries to get the property/ field and to get the instance or type, whether it is an instance or static property. _methodCommands.SetGetter
takes currently two expressions Expression<Func<TResult>> expression
, Expression<Func<TResult>> valueExpression
. Now its searches for the correct getter method and replaces it with the method from the valueExpression
(Method adopted from this SO answer here). But here it fails to get the pointer from any of these methods.
public class Commands
{
private readonly IFieldCommands _fieldCommands;
private readonly IPropertyCommands _propertyCommands;
private readonly IMethodCommands _methodCommands;
public Commands()
{
_fieldCommands = new FieldCommands();
_propertyCommands = new PropertyCommands();
_methodCommands = new MethodCommands();
}
public void SetProperty<TResult>(Expression<Func<TResult>> expression, TResult value)
{
if (expression == null) { throw new ArgumentNullException(nameof(expression)); }
// Set value with the property setter method
var state = _propertyCommands.Set<TResult>(expression, value);
// Override value fom auto backed field of the property
if (state == null) { state = _fieldCommands.SetBackingField(expression, value); }
// Override getter of the property
if (state == null) { state = _methodCommands.SetGetter<TResult>(expression, () => value); }
if (state == null) { throw new NotImplementedException(); }
}
}
// Example call
var commands = new Commands();
commands.SetProperty<DateTime>(() => DateTime.Now, new DateTime(2000,1,1));
var now = DateTime.Now; // Should equals new DateTime(2000,1,1)