具有未知数量参数的Func <>

use*_*923 14 .net c# generics clr functional-programming

请考虑以下伪代码:

TResult Foo<TResult>(Func<T1, T2,...,Tn, TResult> f, params object[] args)
{
    TResult result = f(args);
    return result;
}
Run Code Online (Sandbox Code Playgroud)

该函数接受Func<>未知数量的泛型参数和相应参数的列表.是否可以用C#编写?如何定义和调用Foo?我怎么传递argsf

dca*_*tro 14

那是不可能的.充其量,您可以拥有一个委托,该委托也接受可变数量的参数,然后让委托解析参数

TResult Foo<TResult>(Func<object[], TResult> f, params object[] args)
{
    TResult result = f(args);
    return result;
}
Run Code Online (Sandbox Code Playgroud)


Foo<int>(args =>
{
    var name = args[0] as string;
    var age = (int) args[1];

    //...

    return age;
}, arg1, arg2, arg3);
Run Code Online (Sandbox Code Playgroud)


Ren*_*újo 13

您可以使用DelegateDynamicInvoke.

就这样,你并不需要能够处理object[]f.

TResult Foo<TResult>(Delegate f, params object[] args)
{
    var result = f.DynamicInvoke(args);
    return (TResult)Convert.ChangeType(result, typeof(TResult));
}
Run Code Online (Sandbox Code Playgroud)

用法:

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

Foo<bool>(f,"Jon", 40, true);
Run Code Online (Sandbox Code Playgroud)

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


注意:

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

public static bool Method(string name, int age)
{
    ...
}
var method = (Func<string, int, bool>)Method;
Foo<bool>(method, "Jon", 40);
Run Code Online (Sandbox Code Playgroud)

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

  • 嗯...这种知识可能带来的恶作剧:) (2认同)

Mic*_*zyn 7

使用 lambda 表达式可以很容易地做到这一点:

TResult Foo<Tresult>(Func<TResult> f)
{
  TResult result = f();
  return result;
}
Run Code Online (Sandbox Code Playgroud)

然后用法可能是这样的:

var result = Foo<int>(() => method(arg1, arg2, arg3));
Run Code Online (Sandbox Code Playgroud)

哪里method可以返回任意方法int

通过这种方式,您可以直接通过 lambda 传递任意数量的任何参数。