开发者

Create a delegate with arbitrary parameters

开发者 https://www.devze.com 2023-01-25 15:10 出处:网络
I have a System.Reflection.MethodInfo and would like to have a method that creates a delegate(preferably a Func<...> or an Action<...>) that represents that method, given an instance to invoke i

I have a System.Reflection.MethodInfo and would like to have a method that creates a delegate(preferably a Func<...> or an Action<...>) that represents that method, given an instance to invoke it on.

So ideally I would like something like the following psuedo-code:

public TDelegate GetMethod<TDelegate>(MethodInfo methodToRepresent, object instanceToInvokeOn)
{
    return (TDelegate)((parameters....) => methodToRepresent.Invoke(instanceToInvokeOn, all parameters in an object[]));
}

where TDelegate represents the signature of the represented method. If the signatures don't match, an exception should be thrown.

I realise I probably can't achieve this with a simple lambda expression, since its parametertypes must be known at compile-time. Perhaps I need to construct a delegate from scratch? Is it possible to create a delegate by specifying its body and parameters seperately?

开发者_如何学运维

Thank you


I don't really understand your question. But perhaps you want this:

public TDelegate GetMethod<TDelegate>(MethodInfo methodToRepresent, object instanceToInvokeOn)
  where TDelegate:class
{
   return (TDelegate)(object)Delegate.CreateDelegate(typeof(TDelegate), instanceToInvokeOn, methodToRepresent);
}


You can do this with the following method. Note that you can't really create a generic Action<...> using this method because, as you say, the types are not known at compile time. But this gets you pretty close.

public delegate void DynamicInvokeDelegate(params object[] args);

public static DynamicInvokeDelegate CreateDynamicInvokeDelegate(MethodInfo method, object instance) {
    return args => method.Invoke(instance, args);
}

If you need the delegate to return a value:

public delegate object DynamicInvokeWithReturnDelegate(params object[] args);

public static DynamicInvokeWithReturnDelegate CreateDynamicInvokeWithReturnDelegate(MethodInfo method, object instance) {
    return args => method.Invoke(instance, args);
}

EDIT:

It actually looks like you might be wanting this code:

public static T GetDelegate<T>(MethodInfo method, object instance)
    where T : class
{
    return (T)(object)Delegate.CreateDelegate(typeof(T), instance, method);
}

The (object) cast is required, since the compiler will not allow you to cast Delegate to any random type, and you cannot constrain T to be a delegate. Casting through object satisfies the compiler.

0

精彩评论

暂无评论...
验证码 换一张
取 消