具有未知数量参数的Func

请考虑以下伪代码:

TResult Foo(Func f, params object[] args) { TResult result = f(args); return result; } 

该函数接受具有未知数量的generics参数的Func和相应参数的列表。 是否可以用C#编写? 如何定义和调用Foo ? 如何将args传递给f

那是不可能的。 最好的情况是,您可以拥有一个也可以获取可变数量参数的委托,然后让委托解析参数

 TResult Foo(Func f, params object[] args) { TResult result = f(args); return result; } 

 Foo(args => { var name = args[0] as string; var age = (int) args[1]; //... return age; }, arg1, arg2, arg3); 

您可以将DelegateDynamicInvoke一起使用。

有了它,你不需要处理f object[]

 TResult Foo(Delegate f, params object[] args) { var result = f.DynamicInvoke(args); return (TResult)Convert.ChangeType(result, typeof(TResult)); } 

用法:

 Func f = (name, age, active) => { if (name == "Jon" && age == 40 && active) { return true; } return false; }; Foo(f,"Jon", 40, true); 

我创建了一个小提琴,展示了一些例子: https : //dotnetfiddle.net/LdmOqo


注意:

如果要使用method group ,则需要对Func使用explict强制转换:

 public static bool Method(string name, int age) { ... } var method = (Func)Method; Foo(method, "Jon", 40); 

小提琴: https : //dotnetfiddle.net/3ZPLsY

在某些情况下,你可能会躲过这样的伎俩:

 public static class MyClass { private static T CommonWorkMethod(Func wishMultipleArgsFunc) { // ... do common preparation T returnValue = wishMultipleArgsFunc(); // ... do common cleanup return returnValue; } public static int DoCommonWorkNoParams() => CommonWorkMethod(ProduceIntWithNoParams); public static long DoCommonWorkWithLong(long p1) => CommonWorkMethod(() => ProcessOneLong(p1)); public static string DoCommonWorkWith2Params(int p1, long p2) => CommonWorkMethod(() => ConvertToCollatedString(p1, p2)); private static int ProduceIntWithNoParams() { return 5; } } 

您可以尝试类似于我在此处发布的内容: https : //stackoverflow.com/a/47556051/4681344

它将允许任意数量的参数,并强制执行其类型。

 public delegate T ParamsAction(params object[] args); TResult Foo(ParamsAction f) { TResult result = f(); return TResult; } 

简单地说……

 Foo(args => MethodToCallback("Bar", 123));