zoukankan      html  css  js  c++  java
  • [C#6] 7-索引初始化器

    0. 目录

    C#6 新增特性目录

    1. 老版本的代码

    1 private static void Main()
    2 {
    3     var dictionary = new Dictionary<int, string> {
    4         { 1, "Value1" },
    5         { 2, "Value2" },
    6         { 3, "Value3" }
    7     };
    8 }

    早C#3中引入的集合初始化器,可是让我们用上面的语法来在声明一个字典或者集合的时候立即初始化一些项进去,其实在C#3中这是个语法糖,实质编译后的结果是调用字典或者集合的Add方法逐一添加这些项。但是有一点小小的不直观。先看看这个版的IL吧:

     1 .method private hidebysig static void  Main() cil managed
     2 {
     3   .entrypoint
     4   // Code size       47 (0x2f)
     5   .maxstack  4
     6   .locals init ([0] class [mscorlib]System.Collections.Generic.Dictionary`2<int32,string> dictionary)
     7   IL_0000:  nop
     8   IL_0001:  newobj     instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32,string>::.ctor()
     9   IL_0006:  dup
    10   IL_0007:  ldc.i4.1
    11   IL_0008:  ldstr      "Value1"
    12   IL_000d:  callvirt   instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32,string>::Add(!0,
    13                                                                                                                 !1)
    14   IL_0012:  nop
    15   IL_0013:  dup
    16   IL_0014:  ldc.i4.2
    17   IL_0015:  ldstr      "Value2"
    18   IL_001a:  callvirt   instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32,string>::Add(!0,
    19                                                                                                                 !1)
    20   IL_001f:  nop
    21   IL_0020:  dup
    22   IL_0021:  ldc.i4.3
    23   IL_0022:  ldstr      "Value3"
    24   IL_0027:  callvirt   instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32,string>::Add(!0,
    25                                                                                                                 !1)
    26   IL_002c:  nop
    27   IL_002d:  stloc.0
    28   IL_002e:  ret
    29 } // end of method Program::Main

    本质是Add方法的调用.C#6引入了一种新语法来进一步的优化这种写法。

    2. 索引初始化器

    1 private static void Main()
    2 {
    3     var dictionary = new Dictionary<int, string>
    4     {
    5         [1] = "Value1",
    6         [2] = "Value2",
    7         [3] = "Value3"
    8     };
    9 }

    看起来直观许多了吧,其实是一种语法改进。编译结果也有些许差异,如下:

     1 .method private hidebysig static void  Main() cil managed
     2 {
     3   .entrypoint
     4   // Code size       47 (0x2f)
     5   .maxstack  4
     6   .locals init ([0] class [mscorlib]System.Collections.Generic.Dictionary`2<int32,string> dictionary)
     7   IL_0000:  nop
     8   IL_0001:  newobj     instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32,string>::.ctor()
     9   IL_0006:  dup
    10   IL_0007:  ldc.i4.1
    11   IL_0008:  ldstr      "Value1"
    12   IL_000d:  callvirt   instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32,string>::set_Item(!0,
    13                                                                                                                      !1)
    14   IL_0012:  nop
    15   IL_0013:  dup
    16   IL_0014:  ldc.i4.2
    17   IL_0015:  ldstr      "Value2"
    18   IL_001a:  callvirt   instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32,string>::set_Item(!0,
    19                                                                                                                      !1)
    20   IL_001f:  nop
    21   IL_0020:  dup
    22   IL_0021:  ldc.i4.3
    23   IL_0022:  ldstr      "Value3"
    24   IL_0027:  callvirt   instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32,string>::set_Item(!0,
    25                                                                                                                      !1)
    26   IL_002c:  nop
    27   IL_002d:  stloc.0
    28   IL_002e:  ret
    29 } // end of method Program::Main

    主要差异在于老语法是调用Add方法,新语法是用的索引器的set访问器(set_Item)。

    既然是索引,那么就索引就不仅仅只能是int,也可以是string,任意的自定义类型。

    3. Example

    namespace csharp6
    {
        internal class Program
        {
            public class Person
            {
                public string Name { get; set; }
                public int Age { get; set; }
    
                private Dictionary<string, Address> _cache = new Dictionary<string, Address>();
    
                public Address this[string name]
                {
                    get { return _cache[name]; }
                    set { _cache[name] = value; }
                }
            }
    
            public class Address
            {
                public string Name { get; set; }
                public string Zip { get; set; }
            }
    
            private static void Main()
            {
                //string索引
                var colorMap = new Dictionary<string, ConsoleColor>
                {
                    ["Error"] = ConsoleColor.Red,
                    ["Information"] = ConsoleColor.Yellow,
                    ["Verbose"] = ConsoleColor.White
                };
    
                //枚举索引
                var colors = new Dictionary<ConsoleColor, string>
                {
                    [ConsoleColor.Red] = "#F00",
                    [ConsoleColor.Green] = "#0F0",
                };
    
                //自定义类型的索引器支持
                Person person = new Person
                {
                    Name = "blackheart",
                    Age = 1,
                    ["home"] = new Address { Name = "北京市", Zip = "100000" },
                    ["work"] = new Address { Name = "南京市", Zip = "200000" }
                };
    
                //自定义类型索引
                var persons = new Dictionary<Person, List<Address>>
                {
                    [new Person { Name = "blackheart", Age = 1 }] = new List<Address> {
                        new Address { Name = "北京市", Zip = "100000" }
                    },
                    [new Person { Name = "blackheart", Age = 1 }] = new List<Address> {
                        new Address { Name = "南京市", Zip = "200000" }
                    },
                };
            }
        }
    }

    4. 总结

    从本质来看,[xxx]=yyy这种语法,xxx可以是任意类型,凡是有索引器支持的类型,均可以使用这种语法。简单直接明了。

  • 相关阅读:
    模板集合
    [NOIP2005普及组]循环(高精度+数学)
    KEYENCE Programming Contest 2021
    AtCoder Regular Contest 111
    Educational Codeforces Round 99 (Rated for Div. 2)
    AtCoder Beginner Contest 183翻车记
    上古退役选手康复训练1——CSP2020J-2
    [SNOI2020]取石子(数学+打表找规律)
    selenium爬取拉勾网招聘信息
    scrapy将爬取的数据存入MySQL数据库
  • 原文地址:https://www.cnblogs.com/linianhui/p/csharp6_index-initializers.html
Copyright © 2011-2022 走看看