[英]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 版)中提到了這一點。
更新:出於好奇,我檢查了優化是否也適用於其他地方。 只要左側變量是ref
或out
參數,它似乎就可以工作。 例如這個:
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.