• [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可以是任意类型,凡是有索引器支持的类型,均可以使用这种语法。简单直接明了。

  • 相关阅读:
    jquery实现瀑布文字
    文本域、bootstrap-table显示以及MySQL三者间的换行符问题
    Mybatis框架的搭建和基本使用方法
    解决ajax多次绑定问题
    浅析JSONP与CROS技术解决跨域问题
    使用Ajax+nodejs实现页面头像上传功能
    自写滚屏组件
    express框架的ejs模板引擎渲染html页面
    自写轮播组件
    mousewheel事件细节
  • 原文地址:https://www.cnblogs.com/linianhui/p/csharp6_index-initializers.html
Copyright © 2020-2023  润新知