在C#中正确固化

问题描述 投票:33回答:2

给出了DoSomething方法,该方法采用(无参数)函数并以某种方式对其进行处理。是否有比下面的代码片段更好的方法来为带有参数的函数创建“重载”?

public static TResult DoSomething<TResult>(Func<TResult> func)
{
    //call func() and do something else
}

public static TResult DoSomething<T0, TResult>(
    Func<T0, TResult> func,
    T0 arg0)
{
    return DoSomething(() => func(arg0));
}

public static TResult DoSomething<T0, T1, TResult>(
    Func<T0, T1, TResult> func,
    T0 arg0, T1 arg1)
{
    return DoSomething(arg => func(arg, arg1), arg0);
}

public static TResult DoSomething<T0, T1, T2, TResult>(
    Func<T0, T1, T2, TResult> func,
    T0 arg0, T1 arg1, T2 arg2)
{
    return DoSomething(arg => func(arg, arg1, arg2), arg0);
}
c# lambda currying
2个回答
31
投票

编辑:如评论中所述,这是部分应用程序,而不是临时的。我写了一个blog post on my understanding of the difference,人们可能会发现它很有趣。

嗯,这并没有什么特别的区别-但我从“调用DoSomething”部分中分离出了currying部分:

public static Func<TResult> Apply<TResult, TArg> (Func<TArg, TResult> func, TArg arg)
{
    return () => func(arg);
}

public static Func<TResult> Apply<TResult, TArg1, TArg2> (Func<TArg1, TArg2, TResult> func,
                                                          TArg1 arg1, TArg2 arg2)
{
    return () => func(arg1, arg2);
}

// etc

然后:

DoSomething(Apply(foo, 1));

这样,您就可以在其他情况下重用currying代码,包括您不想立即调用新返回的委托的情况。 (例如,您可能想稍后再咖喱。)


0
投票

@ Jon Skeet的答案是正确的,但是用手书写所有可能的重载都是疯狂的事情,因此您可以使用像Curryfy这样的库来为您完成此工作。 Curryfy lib特别公开了Curry,UnCurry和ApplyPartial扩展方法,并且有很多重载。

© www.soinside.com 2019 - 2024. All rights reserved.