1

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)
Dragonblf
  • 115
  • 1
  • 8
  • Can you tell us more what you are trying to achieve? If your method is already runtime generated, using another runtime generated method instead should be easier to do as using not support, implementation and plattform dependant hacks. – thehennyy Apr 17 '20 at 08:23
  • @thehennyy Added some more information. – Dragonblf Apr 17 '20 at 09:32

0 Answers0