C# 6.0 功能预览 (一)

一、索引的成员和元素初始化

1.1 原始初始化集合 Dictionary

1.2 键值初始化集合 Dictionary

1.3 运算符 $ 初始化集合 Dictionary

二、自动属性的初始化

一不小心发现 C# 已经到 6.0 了,现在项目中使用的还是 4.0,这节奏,完全跟不上啊!

虽然自己也没有使用过 6.0,既然看到了,就拿出来和园有分享一下。

看到了@dotnetgeek的评论,非常感谢,认为是给我这样浮躁的人善意的警告,不应该盲目跟风追新,应该老老实实把现在的搞清楚,万变不离其宗 我发现你是一个微软黑粉,语言的更新仅仅是多了一些特性,你懂C#4.0就可以很轻松的掌握6.0,这不是一个新技术。很多人都说跟不上,我不以为然,比如以前的委托,到了C#新版本出现了Action<T>之类的,咋一看,以为是新东西,但是经过了解之后,就知道是语法糖,所以,你懂的话,根本就不怕更新快,相反,反而会提高你的编程效率

一、索引的成员和元素初始化

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
        // ...
    }

注意:上面的情况,属性是只读的没有定义 setter。属性是在声明时被赋值的。带有 setter 的读/写属性也是支持的。

更多内容请参考http://msdn.microsoft.com/en-us/magazine/dn683793.aspx

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏猿人谷

String.valueOf()

1. 由 基本数据型态转换成 String String 类别中已经提供了将基本数据型态转换成 String 的 static 方法 也就是 String....

20770
来自专栏赵俊的Java专栏

LeetCode 917 Reverse Only Letters

将字符串转为字符数组,用两个指针,从两端向中间走, 依次找下一个字母进行交换,直到两个指针相碰撞。

11120
来自专栏拭心的安卓进阶之路

深入理解 Java 反射:Field (成员变量)

深入理解 Java 反射系列: 深入理解 Java 反射:Class (反射的入口) 深入理解 Java 反射:Field (成员变量) 深入理解 Java ...

84780
来自专栏java学习

重要通知!小编出新的Java练习题已经公布答案了!!!

一、选择题和问答题 1、在一个java原文件中,import, class, package语句的顺序是(D)。 A. import classpackage ...

43280
来自专栏闻道于事

Java之面向对象概述,类,构造方法,static,主方法,对象

一、面向对象概述 面向过程 “面向过程”(Procedure Oriented)是一种以过程为中心的编程思想。这些都是以什么正在发生为主要目标进行编程,不同于...

34350
来自专栏Spark学习技巧

Java反射机制深入详解

一.概念   反射就是把Java的各种成分映射成相应的Java类。   Class类的构造方法是private,由JVM创建。   反射是java语言的一个特性...

1.7K70
来自专栏Android干货园

Kotlin中级(9)- - - Kotlin类之数据类、密封类、内部类.md

上面的代码我们可以看到结构出来的变脸可以直接拿来用,比如数据体Leaf中的size属性,componentN函数群会按照数据体Leaf中属性声明的顺序,从com...

10820
来自专栏函数式编程语言及工具

泛函编程(13)-无穷数据流-Infinite Stream

    上节我们提到Stream和List的主要分别是在于Stream的“延后计算“(lazy evaluation)特性。我们还讨论过在处理大规模排列数据集时...

19750
来自专栏程序员同行者

python enumerate 函数用法

14840
来自专栏Linyb极客之路

Java中的自动装箱与拆箱

自动装箱和拆箱从Java 1.5开始引入,目的是将原始类型值转自动地转换成对应的对象。自动装箱与拆箱的机制可以让我们在Java的变量赋值或者是方法调用等情况下使...

9420

扫码关注云+社区

领取腾讯云代金券