5月
13
2019
分類:
最近更新:
2019-07-16
.NET 筆記 - Anonymous Type List
如何配置一個匿名型別串列。
首先,複習下列定義已知型別串列的語法。
int[] int_list1 = new int[] {1, 3};
var int_list2 = new int[] {1, 3};
var int_list3 = new [] {1, 3};
var list41 = new double[] {1, 3, 5.5};
var list42 = new [] {1, 3, 5.5};
Console.WriteLine(list41.GetType() == list42.GetType());
// error CS0826: 找不到隱含類型陣列的最佳類型
//var list5 = new [] {1, 2, "s"};
第一個例子是明確宣告等號兩邊型別的語法,也是最傳統的語法。
第二個例子引入型別推斷語法,等號右邊明確宣告此處將配置一個整數型別的陣列。所以明眼即可推斷左值之型別必為整數型別陣列。
第三個例子則更進一步,連等號右邊也不明確宣告資料型別。而讓 C# 編譯器先從陣列的資料內容推斷右邊的陣列型別,再依此推斷左邊的型別。這語法要求陣列的所有元素之型別皆可互相隱含轉換,編譯器再從中選出一個不會損失資料精度的型別。例如 new [] {1, 3, 5.5}
將推斷為 double[]
而非 int[]
以保證 5.5 不會變成 5 。若有一個元素的型別不合群,那編譯器就會拋出無法決定最適型別的錯誤。
當有兩個或多個匿名型別之欄位型別與順序相同時,編譯器內部會將它們視為同一型別。因此,當多個匿名型別變數的宣告內容相同時,也允許將它們放在一個串列中,如此就得到一個匿名型別串列。如下例:
using System;
using System.Linq;
var data1 = new {
name = "a",
latitude = 0.0,
longitude = 0.0
};
var data2 = new {
name = "b",
latitude = 1.0,
longitude = 1.0
};
var data_list = new [] {data1, data2}.ToList();
- 如果我們在配置匿名串列時,還不知道各元素的具體值,那麼我們需要先定義一個初始元素。這個初始元素只是為了讓編譯器推斷型別。
- 匿名型別實體的欄位皆是唯讀,因此提供編譯器推斷型別的初始元素無法重用。實際使用時,配置串列後就會移除。
- 後續加入匿名型別串列的元素,也要保持相同的欄位順序。
using System;
using System.Linq;
var data_list = new [] {
new {
name = "",
latitude = 0.0,
longitude = 0.0
}
}.ToList();
data_list.RemoveAt(0);
for (var i = 0; i < 10; ++i) {
data_list.Add(new {
name = $"pos {i}",
latitude = i,
longitude = i
});
}
如果是熟悉 PHP, Python, JavaScript 等動態型別語言的使用者,應該會覺得這樣的語法有些彆扭。這算是一個動態型別語言和靜態型別語言之語法差異的例子。寫這些彆扭的語法,是為了方便編譯器判斷型別。
參考: