【问题标题】:Why can't you destructure to a tuple with only one value?为什么不能解构为只有一个值的元组?
【发布时间】:2016-11-20 23:20:38
【问题描述】:

在 C# 7 中,apparently 无法解构为只有一项的元组。

ValueTuple<T1> 存在,所以不是因为这个。

并且向后兼容意味着带有一个参数的Deconstruct 方法也必须是合法的:

public void Deconstruct(out int i)

那你为什么不能写:

var (num) = foo;

仅仅是因为没有合理的用例吗?

【问题讨论】:

  • 我猜是为了减轻var num = foovar (num) = foo 之间的混淆,特别是因为括号很少会改变程序的含义(不包括操作顺序)。这样的权衡可能不值得,因为正如您所指出的,解构单个参数并没有有用。
  • 我敢打赌,在某些情况下,大括号标识符表达式会产生歧义。
  • 一般来说,一元组和一解构会引起各种语法歧义。而且,它们似乎不是很有用。此时,功能规范已将此限制内置到语法中(请参阅 github.com/dotnet/roslyn/blob/master/docs/features/…github.com/dotnet/roslyn/blob/master/docs/features/…
  • 我们在 VB 中使用 optional refs,并希望切换到 C# 并使用元组(因为 C# 不会添加 optional refs,这完全是另一个问题)。但我们不能,因为元组不能只解构第一个返回值。许多其他语言有 3 个点来跳过剩余的值。

标签: c# destructuring c#-7.0


【解决方案1】:

我的猜测:考虑以下情况:

int num;
(num) = foo;

如果foo 定义了一个带有out int 的解构函数和一个隐式的int 强制转换运算符,那么在这种情况下应该调用哪个将是不明确的

在这种特定情况下可能会出现编译错误,而我猜想允许一般情况,但是正如你所提到的,没有用例并且语法会令人困惑,也许不允许它是有意义的完全没有

【讨论】:

    【解决方案2】:

    我正在使用 Visual Studio 2017 RC。我发现 Connect();您列出的参考不正确。您列出的示例语法确实可以编译和工作。

    作为测试,我使用了以下代码:

    public class Foo
    {
        public int Bar { get; set; }
    
        public void Deconstruct(out int bar)
        {
            bar = Bar;
        }
    }
    
    var foo = new Foo { Bar = 3 };
    var (num) = foo; //num is an int with a value of 3
    var obj = foo; //obj is a Foo object with the same reference as foo
    

    在上面的示例中,num 变量是一个值为 3 的 intobj 变量是一个 Foo 对象,其引用与 foo 相同。

    以下内容无法编译:

    (int num) = foo; 
    (var num) = foo;
    //Both give error: The name `num` does not exist in the current context.
    

    【讨论】:

    • 有趣!让我们看看它到达 RTM 后会发生什么。
    猜你喜欢
    • 1970-01-01
    • 2016-11-12
    • 2021-06-16
    • 2021-06-21
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    相关资源
    最近更新 更多