繁体   English   中英

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

[英]What is the name of this syntax in C# (multiple tuple-like assignment)?

我在 MS 文档中发现了这种语法:

public NewsStoryViewModel(DateTimeOffset published, string title, string uri) =>
        (Published, Title, Uri) = (published, title, uri);

它在一个语句中进行多项赋值,但我不太确定它叫什么或它是如何工作的。

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

PS 如果有人感兴趣, 这里会提到

PPS 我想知道的不是 {} 的缺失,而是第 2 行的“花哨”分配而不是传统分配。

它是一个被解构为类属性的元组。

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

解构适用于开箱即用的元组。 有关详细信息,请参阅https://docs.microsoft.com/en-us/dotnet/csharp/tuples#deconstruction

我不知道他们是否有专门在构造函数中执行此操作的官方术语,它被称为解构作为一般模式。 只要赋值的右边有一个合适的Deconstruct方法,你就可以从一个类型中提取值,像这样批量执行赋值。 对于元组,这个:

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 文档中一样使用它们 - 在一行中编写基本的构造函数:

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 编译器识别这种模式并避免实际创建元组。 如果将其放入反编译器,您将看到生成的代码与 for 相同:

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

我不知道它是否在任何地方都有记录,但要归功于 Jon Skeet,他在他的 C# in Depth(第 4 版)中提到了这一点。

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

public void Deconstruct(out int prop1, out object prop2, out string prop3) =>
    (prop1, prop2, prop3) = (_prop1, _prop2, _prop3);

生成与此等效的代码:

public void Deconstruct(out int prop1, out object prop2, out string prop3)
{
    int temp1 = _prop1;
    object temp2 = _prop2;
    string temp3 = _prop3;
    prop1 = temp1;
    prop2 = temp2;
    prop3 = temp3;
}

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

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

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

C# 7.0:

public NewsStoryViewModel(DateTimeOffset published, string title, string uri) =>
        (Published, Title, Uri) = (published, title, uri);

由于已发布、标题和 Uri 已经定义,您可以像上面一样直接分配它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM