我有一个泛型函数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上使用它。
答案 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"));