[C#6] 7-索引初始化器

简介: 0. 目录 C#6 新增特性目录 1. 老版本的代码 1 private static void Main() 2 { 3 var dictionary = new Dictionary { 4 { 1, "Value1" }, 5 { 2,...

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

作者: Blackheart
目录
相关文章
|
3月前
|
C# 开发者
C# 9.0中的模块初始化器:程序启动的新控制点
【1月更文挑战第14天】本文介绍了C# 9.0中引入的新特性——模块初始化器(Module initializers)。模块初始化器允许开发者在程序集加载时执行特定代码,为类型初始化提供了更细粒度的控制。文章详细阐述了模块初始化器的语法、用途以及与传统类型初始化器的区别,并通过示例代码展示了如何在实际项目中应用这一新特性。
|
1月前
|
自然语言处理 C# 数据安全/隐私保护
50.c#:string类初始化
50.c#:string类初始化
12 1
|
3月前
|
存储 C# 容器
掌握 C# 变量:在代码中声明、初始化和使用不同类型的综合指南
变量是用于存储数据值的容器。 在 C# 中,有不同类型的变量(用不同的关键字定义),例如: int - 存储整数(没有小数点的整数),如 123 或 -123 double - 存储浮点数,有小数点,如 19.99 或 -19.99 char - 存储单个字符,如 'a' 或 'B'。Char 值用单引号括起来 string - 存储文本,如 "Hello World"。String 值用双引号括起来 bool - 存储具有两个状态的值:true 或 false
37 2
|
9月前
|
C#
C#中声明、初始化和实例化
C#中声明、初始化和实例化