这种语法在C#(类似于多元组的赋值)中的名称是什么?

这种语法在C#(类似于多元组的赋值)中的名称是什么?,c#,C#,我在MS文档中发现了以下语法: public NewsStoryViewModel(DateTimeOffset published, string title, string uri) => (Published, Title, Uri) = (published, title, uri); 它在一个语句中执行多个赋值,但我不太确定它的名称或工作方式 这是一种通过假装这些是元组来进行多重赋值的技巧,还是它有自己的名称 另外,如果有人感兴趣,我们会提到的 p.p.S.我想

我在MS文档中发现了以下语法:

public NewsStoryViewModel(DateTimeOffset published, string title, string uri) =>
        (Published, Title, Uri) = (published, title, uri);
它在一个语句中执行多个赋值,但我不太确定它的名称或工作方式

这是一种通过假装这些是元组来进行多重赋值的技巧,还是它有自己的名称

另外,如果有人感兴趣,我们会提到的


p.p.S.我想知道的不是{}的缺失,而是第二行的“奇特”作业,而不是传统作业

它是解构为类属性的元组

public NewsStoryViewModel(DateTimeOffset published, string title, string uri) {
    // tuple
    var myTuple = (published, title, uri);
    // deconstruction
    (Published, Title, Uri) = myTuple;
}

解构适用于开箱即用的元组。有关详细信息,请参见。

第二行基本上充当属性的设置器。在C#7.0之前,我们可以做到:

public NewsStoryViewModel(DateTimeOffset published, string title, string uri) 
{
        Published = published;
        Title = title; 
        Uri = uri;
}
C#7.0:


正如已经发布的一样,Title和Uri已经定义好了,可以像上面那样直接分配它们。

我不知道它们是否有在构造函数中这样做的官方术语,具体来说,它被称为通用模式。只要赋值的右侧有一个合适的
解构
方法,就可以从类型中提取值,并像这样批量执行赋值。对于元组,这是:

var (x, y, z) = (1, 2, 3);
在道德上等同于

var tuple = (1, 2, 3);
var x = tuple.Item1;
var y = tuple.Item2;
var z = tuple.Item3;
左侧可以有任何可赋值变量,它们可以是局部变量、字段或构造函数中的“仅获取属性”。使用这是个人偏好和代码风格,我通常在MSDN文档中使用它们-在一行中编写基本的CTOR:

class C
{
    private int Prop1 { get; }
    private D Prop2 { get; }
    private string Prop3 { get; }

    public C(int prop1, D prop2, string prop3) =>
        (Prop1, Prop2, Prop3) = (prop1, prop2, prop3);
}
一个有趣的事实是,Roslyn编译器识别这种模式,并避免实际创建元组。如果将其放入反编译器,您将看到生成的代码与的代码相同:

public(int-prop1,D-prop2,string-prop3)
{
Prop1=Prop1;
Prop2=Prop2;
Prop3=Prop3;
}
我不知道它是否在任何地方被记录下来,但这要归功于Jon Skeet,他在《深度》C#Depth(第四版)中提到了这一点

更新: 出于好奇,我检查了优化是否也适用于其他地方。似乎只要左侧变量是
ref
out
参数,它就可以工作。例如:

public void解构(out int prop1、out object prop2、out string prop3)=>
(prop1、prop2、prop3)=(prop1、prop2、prop3);
生成与此等效的代码:

public void解构(out int prop1、out object prop2、out string prop3)
{
int temp1=_prop1;
对象temp2=_prop2;
字符串temp3=_prop3;
prop1=temp1;
prop2=temp2;
prop3=temp3;
}

我的猜测是,由于IL在分配给“正常”变量和分配给
ref
变量之间有所不同,因此第二种情况下根本没有实现优化,但我可能错了。

这些是元组,实际上,从C#7开始就完全支持到语言中。@Alejandro这是一种表达式体方法(有3个参数),不是元组。它看起来也是一个构造函数……它正在初始化viewmodel的3个属性。@adt我也这么认为,但我没有任何
Desconstruct
方法,但这确实有compile@RonBeyer我不够具体,对这个问题做了一点修改,我想知道的不是表达身体的方法,但另一行它的语法非常混乱,因为左右两部分看起来都一样,但左边的是Deconstruction语法,右边的是元组声明,但感谢你的回答,这澄清了问题!Roslyn这样做其实很聪明,我只是觉得这样写会有一些开销:)
class C
{
    private int Prop1 { get; }
    private D Prop2 { get; }
    private string Prop3 { get; }

    public C(int prop1, D prop2, string prop3) =>
        (Prop1, Prop2, Prop3) = (prop1, prop2, prop3);
}