将函数作为参数传递给另一个函数时,如何解构函数调用

时间:2019-08-19 19:16:38

标签: c#

我想将一个返回两个值的函数传递给另一个函数,该函数期望两个值与参数相同。在下面的示例中,我想将GetNum传递给GetLine。

public class Program
{
    public static void Main()
    {
        Console.WriteLine(GetLine(GetNum()));
    }   
    public static (int,string) GetNum() => (5,"five");
    public string GetLine(int n , string s) => $"{n} {s}";
}

有没有可以帮助我的C#语法?

4 个答案:

答案 0 :(得分:3)

您可以执行以下操作:

public static void Main()
{
    Console.WriteLine(GetLine(GetNum()));
}   
public static (int,string) GetNum() => (5,"five");
public static string GetLine((int, string) a) {
    var (number, text) = a;
    return $"{number}, {text}";
}

为什么这样做? (int, string)函数的参数GetLine实际上是一种类型,就像floatdouble一样。因此,将其实际解构到位是没有意义的。在编写函数自变量时,不希望您在此处写任何逻辑-例如,您不能在此处递增数字。您应该只列出参数类型和参数名称。

答案 1 :(得分:3)

函数仅返回一个值(即一个Type),在这种情况下,GetNum返回的是ValueTuple<int, string>

允许GetLine方法与GetNum的返回类型一起使用的一种方法是编写该方法的重载,该方法采用ValueTuple<int, string>并返回传递{{ 1}}和Item1转换为原始方法:

Item2

现在,您可以将一种方法的返回值用作第二种方法的参数:

public string GetLine((int, string) t) => GetLine(t.Item1, t.Item2);

答案 2 :(得分:2)

没有C#语法可以真正实现您想要的功能。具有两个参数的方法(例如您的GetLine()方法)需要传递两个参数,而C#除了提供特定的变量之外,不提供解构元组的方法。由于方法的参数只是值(by-reference参数除外),因此没有任何变量可以将元组解构。

有很多 种不同的方式可以做类似的事情。但是,恕我直言,最接近您想要做的事情看起来像这样:

static class Extensions
{
    public static TResult CallDeconstructed<T1, T2, TResult>(this (T1, T2) tuple, Func<T1, T2, TResult> func)
    {
        return func(tuple.Item1, tuple.Item2);
    }
}

即您可以在元组上调用的扩展方法,该方法会将元组的各个值作为单独的方法参数传递给所提供的方法。使用了这样的东西:

public static void Main()
{
    //Console.WriteLine(GetLine(GetNum()));
    Console.WriteLine(GetNum().CallDeconstructed(GetLine));
}
public static (int, string) GetNum() => (5, "five");
public static string GetLine(int n, string s) => $"{n} {s}";

所有这些,我不确定包括上述内容在内的任何替代方法是否真的比在调用站点编写中间代码好得多:

(int n, string s) = GetNum();
GetLine(n, s);

答案 3 :(得分:0)

有一个模板-看起来像这样:

 public static string GetLine(Action<string, int> passedProc, otherParms) // etc

这需要一个过程。

对于功能,您可以这样做

 public static string GetLine(Function<(string, int)> passedFunc, otherParms) // etc

然后,您可以在GetLine过程中调用passedFunc并返回元组。