C# 7.0 丢弃参数歧义

C# 7.0 discard out parameter ambiguity

来自https://blogs.msdn.microsoft.com/dotnet/2017/03/09/new-features-in-c-7-0/

We allow "discards" as out parameters as well, in the form of a _, to let you ignore out parameters you don’t care about:

p.GetCoordinates(out var x, out _); // I only care about x

考虑以下代码:

void Foo(out int i1, out int i2)
{
    i1 = 1;
    i2 = 2;
}

int _;
Foo(out var _, out _);
Console.WriteLine(_); // outputs 2

问题:

为什么在此上下文中输出 "discard" out 参数?

此外,out var _ 不应该出现 "already defined in scope" 错误吗?

int i;
Foo(out var i, out i);
Console.WriteLine(i); // Error: A local variable or function named 'i'
                      // is already defined in this scope

这是GitHub issue that details the behavior of discards,相关部分是:

However, semantically we want this to create an anonymous variable, and shadow any true variable (e.g. parameter or field) from an enclosing scope named _.
...
We have to be careful with these changes so that any program that uses _ as an identifier and is legal today continues to compile with the same meaning under these revised rules.

_ 仅表示 "discard this parameter" 如果您声明并使用它

  • 作为"designator"(声明表达式)中的标识符,其中包括out参数和元组的解构以及类似的
  • 作为模式匹配中的标识符 (switch ... case int _)
  • 显然也用于声明匿名委托,这些委托必须采用参数以适应委托类型,但您不需要实际参数。

out var _ 是其中之一。

然而,int _; 是一个单独的声明,因此这表明您 "care" 关于这个变量,因此它不是丢弃。

因此你得到一个名称为_的普通变量,这仍然是合法的。正如预期的那样,这从方法调用中获取了值 2。