如何将带有一些绑定参数的任意函数传递给另一个函数?

时间:2013-04-03 17:39:57

标签: c# reflection delegates

我有一个泛型函数CallLater,它应该接受一个任意的其他函数,并可能稍后用一些参数调用它。应支持所有类型的功能 - 静态,实例,私有,公共。在反射的帮助下,在CallLater中动态分析和构造参数。但是,在将函数传递给CallLater之前,其中一些可能需要绑定到固定值。

例如:

void CallLater(Delegate d) {
  // Expects a function that returns string and has one argument of arbitrary type.
  if (d.Method.GetParameters().Length == 1 && 
      d.Method.ReturnType == typeof(string)) {
    object param1 = Activator.CreateInstance(d.Method.GetParameters()[0].ParameterType);
    Console.WriteLine((string)d.DynamicInvoke(param1));
  }
}

// Has one extra float parameter.
string MyFunc(int a, float b) { ... }

我的想法是做那样的事情:

float pi = 3.14f;
CallLater(delegate(int a) { return MyFunc(a, pi); });

但这不适用于编译器抱怨:

Error CS1660: Cannot convert `anonymous method' to non-delegate type `System.Delegate' (CS1660) (test-delegate)

实现目标的正确方法是什么?

P.S。请不要提供声明固定委托类型的解决方案,因为CallLater更复杂,也可能支持可变数量的参数。

P.P.S。可能是我的解决方案是Func,但到目前为止我无法在Mono上使用它。

2 个答案:

答案 0 :(得分:1)

您可以随时重新声明Func

public delegate TReturn FFunc<TArg,TReturn>(TArg arg);

你可以这样使用:

float pi = 3.14f;
CallLater((FFunc<int,string>)(delegate(int a) { return MyFunc(a, pi); }));

答案 1 :(得分:0)

我建议使用匿名函数,在其中调用要执行的方法。这些将在以后执行匿名方法时执行。

private static void ExecuteBoolResult(Func<bool> method)
{
    bool result = method();
    if (!result)
    {
        throw new InvalidOperationException("method did not return true");
    }
}

CheckBoolResult(() => AnotherFunction("with ", 3, " parameters"));
CheckBoolResult(() => AnotherFunction(2, "parameters"));