Делегировать для любого типа метода - С#

Я хочу иметь класс, который будет выполнять любой внешний метод, например:

class CrazyClass
{
  //other stuff

  public AnyReturnType Execute(AnyKindOfMethod Method, 
    object[] ParametersForMethod)
  {
    //more stuff
    return Method(ParametersForMethod) //or something like that
  }
}

Возможно ли это? Есть ли делегат, который принимает любую подпись метода?

Ответ 1

Вы можете сделать это по-другому с помощью Func<T> и закрытия:

public T Execute<T>(Func<T> method)
{
   // stuff
   return method();
}

Затем вызывающий может использовать блокировки для его реализации:

var result = yourClassInstance.Execute(() => SomeMethod(arg1, arg2, arg3));

Преимущество в том, что вы разрешаете компилятору выполнять тяжелую работу для вас, а вызовы и возвращаемые значения метода являются безопасными для всех типов, предоставляют intellisense и т.д.

Ответ 2

Собственно, зависит от того, почему вы хотите это сделать в первую очередь... Я бы сделал это с использованием генератора Func, чтобы CrazyClass все еще не знал параметров.

class CrazyClass
{
    //other stuff

    public T Execute<T>(Func<T> Method)
    {
        //more stuff
        return Method();//or something like that
    }


}

class Program
{
    public static int Foo(int a, int b)
    {
        return a + b;
    }
    static void Main(string[] args)
    {
        CrazyClass cc = new CrazyClass();
        int someargs1 = 20;
        int someargs2 = 10;
        Func<int> method = new Func<int>(()=>Foo(someargs1,someargs2));
        cc.Execute(method);
        //which begs the question why the user wouldn't just do this:
        Foo(someargs1, someargs2);
    }
}

Ответ 3

Я думаю, что вам лучше использовать отражения в этом случае, так как вы получите именно то, что задали в вопросе - любой метод (статический или экземпляр), любые параметры:

public object Execute(MethodInfo mi, object instance = null, object[] parameters = null)
{
    return mi.Invoke(instance, parameters);
}

Класс System.Reflection.MethodInfo.

Ответ 4

public static void AnyFuncExecutor(Action a)
{
    try
    {
        a();
    }
    catch (Exception exception)
    {
        throw;
    }
}