如何为 c#7 元组中的方法参数指定默认值?

How can I specify default values for method parameters in c#7 tuples?

在 C# 中,您可以按照 here. I was playing around with tuples and C#7 (using LinqPad 描述的方式定义默认参数(启用 Preferences -> Queries -> Use Roslyn assemblies),如下所示:

void Main()
{   
    var result=AddTuples((1, 2),  (3, 4));
    Console.WriteLine($"Result is: {result}");
}

(int x, int y) AddTuples((int x, int y) a,  (int x, int y) b)
{
    return (a.x + b.x,  a.y + b.y);
}

这很好用,它显示了 a 和 b 的总和:

Result is: (4, 6)

现在我试图修改 AddTuples 以使用默认参数,但不知何故我不知道如何做。我试过的是这样的:

(int x, int y) AddTuples2((int x, int y) a = (0, 0),  (int x, int y) b = (0, 0))
{
    return (a.x + b.x,  a.y + b.y);
}

但我收到错误消息:

CS1736 Default parameter value for 'a' must be a compile-time constant

CS1736 Default parameter value for 'b' must be a compile-time constant

(通过 DotNetFiddle 在线尝试)

我做错了什么?


更新

感谢您提供的出色答案,我学到了很多东西。让我总结一下:要为元组参数设置默认值,有 3 个可能的选项:

  1. 老式方法:重载方法,在方法体中提供默认值。缺点:如果你有超过2个元组,重载变得很麻烦。
  2. ,在方法体中提供默认值。
  3. 允许方法参数中有 2 个以上的元组,在方法主体中提供默认值

注意: 选项 1.、2. 和 4. 允许指定任何所需的默认值,而选项 3. 仅限于 [=15] 提供的默认值=]关键字。

ab 不是常量。创建新实例的所有内容(无论是结构还是 class)都不会被视为常量,并且方法签名只允许将常量作为默认值。

也就是说,无法从方法签名中默认元组,您必须创建一个单独的方法。

唯一的出路似乎是使用可为空的参数:

(int x, int y) AddTuples2((int x, int y)? a = null, (int x, int y)? b = null)
{
    (int x, int y) aNN = a ?? (0,0);
    (int x, int y) bNN = b ?? (0,0);
    return (aNN.x + bNN.x, aNN.y + bNN.y);
}

您可以指定一个默认值,只要您对 int 个组件中的 default-initialisation 感到满意即可:

public static (int x, int y) AddTuples(
    (int x, int y) a = default((int, int)), 
    (int x, int y) b = default((int, int)))
{
    return (a.x + b.x, a.y + b.y);
}

遗憾的是,您无法为元组的组件提供特定的默认值。

但是,对于您的特定示例(您希望默认为 (0, 0)),这似乎就足够了。


[附录]

此特定示例的另一种方法是使用 params 数组:

public static (int x, int y) AddTuples(params (int x, int y)[] tuples)
{
    return (tuples.Sum(t => t.x), tuples.Sum(t => t.y));
}

然后你可以做:

Console.WriteLine($"Result is: {AddTuples()}");                       // (0, 0)
Console.WriteLine($"Result is: {AddTuples((1, 1))}");                 // (1, 1)
Console.WriteLine($"Result is: {AddTuples((1, 1), (2, 2))}");         // (3, 3)
Console.WriteLine($"Result is: {AddTuples((1, 1), (2, 2), (3, 3))}"); // (6, 6)

Visual Studio 2017 建议对 Patrick 的回答进行以下简化:

(int x, int y) AddTuples2((int x, int y)? a = null, (int u, int v)? b = null)
{
    (int x, int y) = a ?? (0,0);
    (int u, int v) = b ?? (0,0);
    return (x + u, y + v);
}