一、索引的成員和元素初始化 1.1 原始初始化集合 Dictionary 思考一下,下面的單元測試 通過集合初始化器給一個集合賦值 [TestMethod] public void DictionaryIndexWithoutDotDollar() { Dictionary<string, string> builtInDataTypes = new Dictionary<string, string>() { {"Byte", "0 to 255"}, {"Boolean", "True or false."}, {"Object", "An Object."}, {"String", "A string of Unicode characters."}, {"Decimal", "±1.0 × 10e-28 to ±7.9 × 10e28"} }; } 1.2 鍵值對始化集合 Dictionary 盡管上面的代碼有些隱晦,但他還是一個鍵值對集合。如果語法為<index> = <value>的形式,會更加清晰,容易理解。在 C# 6.0 中,就可以通過 C# 對象初始化器和一個新的索引成員語法來初始化。 下面是基於整型元素的初始化: var cppHelloWorldProgram = new Dictionary<int, string> { [10] = "main() {", [20] = " printf(\"hello, world\")", [30] = "}" }; Assert.AreEqual(3, cppHelloWorldProgram.Count); 注意:盡管實例化代碼使用整數作為索引,但 Dictionary<TKey,TValue> 是支持任何類型作為索引(只要該索引支持 IComparable<T>)。 下面介紹一個使用字符串作為索引類型,並使用索引成員初始化器指定元素值 Dictionary<string, string> builtInDataTypes = new Dictionary<string, string> { ["Byte"] = "0 to 255", // ... // Error: mixing object initializers and // collection initializers is invalid // {" Boolean", "True or false."}, ["Object"] = "An Object.", ["String"] = "A string of Unicode characters.", ["Decimal"] = "±1.0 × 10e?28 to ±7.9 × 10e28" }; 1.3 運算符 $ 初始化集合 Dictionary 隨著新的索引成員初始化器出現的還有一個新運算符 “$”(難道他的靈感來自於ps,自己瞎猜的)。字符串索引成員語法是提供給基於字符串索引使用的。使用該新語法,更像是動態成員調用,而非上面字符串的表示。 下面是一個例子 [TestMethod] public void DictionaryIndexWithDotDollar() { Dictionary<string, string> builtInDataTypes = new Dictionary<string, string> { $Byte = "0 to 255", // Using indexed members in element initializers // ... $Boolean = "True or false.", $Object = "An Object.", $String = "A string of Unicode characters.", $Decimal = "±1.0 × 10e?28 to ±7.9 × 10e28" }; Assert.AreEqual("True or false.", builtInDataTypes.$Boolean); } 復制代碼 為了理解運算符“$”,請留意調用的 AreEqual 方法。有沒有注意到 builtInDataTypes 變量調用 dictionary 的成員 “$Boolean”,但是在 dictionary 中沒有 “Boolean” 成員。因為運算符 “$” 調用 dictionary 中的索引成員,就等同於 buildInDataTypes["Boolean"],所以使用運算符 “$” 時,不需要明確指出索引。 作為基於字符串的運算,編譯時沒有驗證字符串索引在 dictionary 中是否存在。也就是說,只要是合法的C#成員(區分大小寫)在運算符 “$”($+”C#成員”)。 更加令人意外的索引成員語法是,考慮了字符串索引在若弱類型數據(如:XML、JSON、CSV、甚至是數據庫查找)種的優勢。下面是一個,使用Newtonsoft.Json框架很方便的使用字符串索引成員的例子。 [TestMethod] public void JsonWithDollarOperatorStringIndexers() { // Additional data types eliminated for elucidation string jsonText = @" { 'Byte': { 'Keyword': 'byte', 'DotNetClassName': 'Byte', 'Description': 'Unsigned integer', 'Width': '8', 'Range': '0 to 255' }, 'Boolean': { 'Keyword': 'bool', 'DotNetClassName': 'Boolean', 'Description': 'Logical Boolean type', 'Width': '8', 'Range': 'True or false.' }, }"; JObject jObject = JObject.Parse(jsonText); Assert.AreEqual("bool", jObject.$Boolean.$Keyword); } 最後需要注意一點,例子可能不是很明顯,上面運算符 “$” 的語法只適用於索引是字符串類型(如Dictionary<string,…>) 二、自動屬性初始化 初始化類總是讓人很厭煩。思考下,例如,一個簡單的自定義集合類型(如,Queue<T>),在其內部維護一個私有 System.Collections.Generic.List<T> 屬性列表。當實例化集合時,就必須初始化這個包含列表的隊列,但是,對於一個屬性,這樣做的合理方案是支持的字段需要有一個初始化器或其他構造函數,但是,這種組合的方式代碼量幾乎會翻番。 用C#6.0中,有一個捷徑:自動屬性初始化。現在,就可以指定直接初始化,代碼如下: internal class Queue<T> { private List<T> InternalCollection { get; } = new List<T> ; // Queue Implementation // ... }