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

C# 如何将带有某些绑定参数的任意函数传递给另一个函数?,c#,reflection,delegates,C#,Reflection,Delegates,我有一个通用函数CallLater,它应该接受一个任意的其他函数,并可能稍后使用一些参数调用它。应该支持所有类型的功能——静态、实例、私有、公共。参数在CallLater中借助反射进行动态分析和构造。但是,在将函数传递给CallLater之前,其中一些可能需要绑定到固定值 例如: void CallLater(Delegate d) { // Expects a function that returns string and has one argument of arbitrary ty

我有一个通用函数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)
实现我的目标的正确方法是什么

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


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

您可以自己重新声明
Func

public delegate TReturn FFunc<TArg,TReturn>(TArg arg);
public delegate TReturn FFunc(TArg arg);
您可以这样使用:

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

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

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"));
private static void ExecuteBoolResult(Func方法)
{
bool result=method();
如果(!结果)
{
抛出新的InvalidOperationException(“方法未返回true”);
}
}
CheckBoolResult(()=>另一个函数(“带”,3,“参数”);
CheckBoolResult(()=>另一个函数(2,“参数”);

params object[]
允许您使用可变数量的参数搜索C#中的术语“currying”。您将显示如下内容:这似乎仅限于一个参数。CallLater应该能够接受任意数量的参数。我是否需要更改CallLater的声明,或者委托参数类型是否可以正常工作?噢,你真的想研究“currying”,就像其他人提到的那样;我认为基于方法中的注释,您只是在寻找这个用例。