具有未知数量参数的Func
请考虑以下伪代码:
TResult Foo(Func f, params object[] args) { TResult result = f(args); return result; }
该函数接受具有未知数量的generics参数的Func
和相应参数的列表。 是否可以用C#编写? 如何定义和调用Foo
? 如何将args
传递给f
?
那是不可能的。 最好的情况是,您可以拥有一个也可以获取可变数量参数的委托,然后让委托解析参数
TResult Foo(Func
Foo(args => { var name = args[0] as string; var age = (int) args[1]; //... return age; }, arg1, arg2, arg3);
您可以将Delegate
与DynamicInvoke
一起使用。
有了它,你不需要处理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));