简体   繁体   English

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

[英]How to pass an arbitrary function with some bound parameters to another function?

I have a generic function CallLater that should accept an arbitrary other function and possibly call it later with some parameters. 我有一个泛型函数CallLater,它应该接受一个任意的其他函数,并可能稍后用一些参数调用它。 All kind of functions should be supported - static, instance, private, public. 应支持所有类型的功能 - 静态,实例,私有,公共。 Parameters are analyzed and constructed dynamically in CallLater with the help of reflection. 在反射的帮助下,在CallLater中动态分析和构造参数。 However, some of them may need to be bound to fixed values before passing the function to the CallLater. 但是,在将函数传递给CallLater之前,可能需要将其中一些绑定到固定值。

For example: 例如:

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) { ... }

My idea was to do something like that: 我的想法是做那样的事情:

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

But this doesn't work as compiler complains: 但这不适用于编译器抱怨:

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

What is the correct approach to achieve my goal? 实现目标的正确方法是什么?

PS Please do not offer the solution to declare a fixed delegate type as CallLater is way more complex and may support variable number of arguments too. PS请不要提供声明固定委托类型的解决方案,因为CallLater更复杂,也可能支持可变数量的参数。

PPS It might be that my solution is Func, but I wasn't able to use it on Mono so far. PPS可能是我的解决方案是Func,但到目前为止我无法在Mono上使用它。

You can always redeclare Func yourself: 您可以随时重新声明Func

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

Which you can use thusly: 您可以这样使用:

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

I'd suggest using anonymous functions in which you call the method you want to execute. 我建议使用匿名函数,在其中调用要执行的方法。 These are executed later when the anonymous method is executed. 这些将在以后执行匿名方法时执行。

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"));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM