Assignment of lambda as a parameter to the universal method caused by reflection

Consider the general method:

class SomeClass
{
    public static void SomeMethod<T>(Func<T>);
}

I would like to name this method using reflection. Here's how I can do it:

_SomeMethod = typeof(SomeClass).GetMethod("SomeMethod",
    BindingFlags.Public | BindingFlags.Static);
Type type = typeof(SomeType); //Actually SomeType is extracted using reflection and it not fixed
MethodInfo toBeCalled = _SomeMethod.MakeGenericMethod(type);
object obj = Activator.CreateInstance(type);
toBeCalled.Invoke(null, () => obj);

But this gives a compilation error:

Error CS1660: Cannot convert `lambda expression' to non-delegate type `object' (CS1660)

Which is absolutely acceptable, but what works?

Please keep in mind that a closure created using lambda is what I need, so don't rule it out.

[UPDATE]

, ; , , , SomeMethod SomeType. functor, . - obj , , ?

+4
3

, , Func<T>, "func" . :

public void SomeMethodInvokerRuntime(Type typeofSomeClass, object obj)
{
    var _SomeMethod = this.GetType().GetMethod("SomeMethodInvoker", 
        BindingFlags.Public | BindingFlags.Static);
    MethodInfo toBeCalled = _SomeMethod.MakeGenericMethod(obj.GetType());
    toBeCalled.Invoke(null, new[]{typeofSomeClass, obj});
}

public static void SomeMethodInvoker<T>(Type typeofSomeClass, T obj)
{
    var _SomeMethod = typeofSomeClass.GetMethod("SomeMethod",
          BindingFlags.Public | BindingFlags.Static);
    MethodInfo toBeCalled = _SomeMethod.MakeGenericMethod(typeof(T));
    Func<T> that = () => obj; // Main part - strongly typed delegate
    toBeCalled.Invoke(null, new[]{that});
}

:

static class Test
{
    public static void SomeMethod<T>(Func<T> f)
    {
        Console.WriteLine((T)(f()));
    }
}

SomeMethodInvoker(typeof(Test), 3);
object obj = "test";

SomeMethodInvokerRuntime(typeof(Test), obj);

, Jon Skeet.

+3

, . , :

var expression = Expression.Constant(obj, type);
var delegateType = typeof(Func<>).MakeGenericType(type);
var func = Expression.Lambda(delegateType, expression).Compile();
toBeCalled.Invoke(null, func);
+3

The simplest form reduced to it, we have this:

void Main()
{
    MethodInfoInvoke(()=> {} );
}

void MethodInfoInvoke(object func)
{
}

Failure with the same error.

Now, if we pass lambda in the delegate, it looks happier:

void Main()
{
    Object obj = new Object();
    Func<object> action = ()=> obj; ;
    MethodInfoInvoke(action);      // accepted!
}
0
source

Source: https://habr.com/ru/post/1598402/


All Articles