3

我有一个通用函数 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)

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

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

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

4

2 回答 2

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); }));
于 2013-04-03T17:47:31.740 回答
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"));
于 2013-10-04T09:22:42.240 回答