C#6

 

1. 只读自动属性(Read-only auto-properties)

C# 6之前我们构建只读自动属性:

1   public string FirstName { get; private set; }
2 public string LastName { get; private set; }

原理解析:就是编译器在生成set访问器时,它的修饰符是private,由上可知所谓的只读只是针对类外部,在类内部还是可以随意修改属性值的。

C# 6中提供了真正的只读自动属性,写法如下:

1   public string FirstName { get; }
2 public string LastName { get; }

原理解析:首先编译器会生成一个readonly的私有字段而get访问器就是返回该字段的值,由上可知该只读自动属性只能在构造函数中为其赋值。

2. 自动属性初始化器(Auto-Property Initializers)

以前自动属性的赋值操作我们只能写在方法中,如构造函数:

1 public Student(string firstName, string lastName)
2 {
3 FirstName = firstName;
4 LastName = lastName;
5 }

但在C# 6中我们可以把赋值操作当作声明的一部份,如下所示:

1   public string FirstName { get; set; } = "Corleone";
2 public string LastName { get; set; } = "Mike";

备注:其实C# 6和之前的版本都一样赋值操作最终都是在方法中完成,但后者明显更简洁直观,所以这是个不错的语法糖。

3. 函数成员的表达式体(Expression-bodied function members)

C# 6中提供的一个新语法:对于只有一条语句的方法体可以简写成表达式。如下面两种情况:

1. 方法(Methods)

1   public Student Create() => new Student();

等同于:

1   public Student Create()
2 {
3 return new Student();
4 }

2. 只读属性(read only properties)

1   public string FullName => string.Format("{0},{1}", FirstName, LastName);

等同于:

1   public string FullName
2 {
3 get
4 {
5 return string.Format("{0},{1}", FirstName, LastName);
6 }
7 }

原理解析:上面的表达式在编译后会生成最原始的方法体和访问器,值得一提的是函数表达式体跟Lambda是两个相似但不相同的东西,函数的表

达式体只能带一句话且不能包含return关键字但Lambda 能带语句块和包含关键字。

4. 使用静态(using static)

C# 6中的一个新语法:使用类型的静态成员时可以省略其类型,如下所示:

1   using static System.String;       // 先导入对应成员类型
2 public bool IsNull(string str) => IsNullOrEmpty(str);

等同于:

1   public bool IsNull(string str) => string.IsNullOrEmpty(str);

总结:该语法糖的目的是使代码变得更简洁,但这个应该是区分使用场景的,如:数学计算(Math类)使用此语法糖的确能够简洁代码提高可读

性,但在某处如果导入过多的类型那么不仅不能提高阅读性反而会增加阅读难度,因为你不知道这些成员具体属于那个类型。还有若类型本身存在

同名成员使用时则会使用类型成员覆盖。

注意:使用静态这一语法糖并不适用扩展方法,因为扩展方法的设计理念就是不修改已有代码且只能在一定范围内使用,所以在特殊情况下需要将

其当作静态方法来使用,那么使用类名调用反而是比较明智的。

5. Null条件运算符(Null-conditional operators)

稍有经验的童鞋都知道在Coding过程中经常要判断变量的值是否为null,类似这种if-else的操作还不少。这使得代码看起来十分不简洁,好在C#6

中提供了解决方法:

1   var student = new Student();
2 var firstName = student?.FirstName;

等同于:

1   var student = new Student();
2
3 string firstName = null;
4 if (student != null)
5 {
6 firstName = student.FirstName;
7 }

使用方法:只需替换成员访问符 . 为 ?. ,若 ?. 左边为null则整个运算符的结果也为null,否则运算符的结果就等于其成员值。假如成员的类型为值

类型则整个表达式返回的类型是对应类型的可空类型,如:

1   int? age = student?.Age;

原理解析: ?. 编译后就是 if 或 三元运算符,非赋值操作(如:call)会编译成 if,赋值操作一般会编译成三元运算符。

6. 字符串插值(String Interpolation)

C# 6中提供了一种新语法来构建格式化字符串,如:

1   var fullName = $"{student.FirstName},{student.LastName}";

等同于:

1   var fullName = string.Format("{0},{1}", student.FirstName, student.LastName);

使用方法:只需在字符串前加上$符号,然后在大括号中填写表达式(字段、方法、Lambdad...)即可。

备注:

1. 字符串插值语法支持以前所有字符串格式设置,如:

1   Console.WriteLine($"平均成绩:{student.GPA:F2}");

注:因为 : 总被编译器解释为表达式与字符串格式的分隔符,所以表达式中若有条件运算符则我们需要用括号来强制编译将其解析成当前语境所要

表达的意义。如:

1   Console.WriteLine($"平均成绩:{(student.GPA > 80 ? student.GPA : 0):F2}");

2. 字符串插值语法可以嵌套,如:

1   var score = $"我的各科成绩:{ $"数学:{student.MathScores};英语:{student.EnglishScore};"}";

原理解析:$"xxx{expression1}xxx{expression2}..." 编译后就是string.Format()。

7. 异常过滤器(Exception Filters)

C# 6中的一个新功能就是异常过滤器,它可以使我们在恰当的时机来应用Catch子句,如:

1   try
2 {
3 throw new WebException("Request timed out..", WebExceptionStatus.Timeout);
4 }
5 catch (WebException webEx) when (webEx.Status == WebExceptionStatus.Timeout)
6 {
7 // Exception handling
8 }

使用方法:try-catch() when()。

总结:异常过滤器最大的亮点就是在使用恰当的情况下可以不丢失异常引发点的堆栈信息,这对程序的排错至关重要。另外它还有很多有意思的用

法,大家可以上网查下。

8. nameof表达式(nameof Expressions)

nameof 表达式的功能是获取成员名称,如抛异常:

1   public string FullName(Student student)
2 {
3 if (student == null)
4 throw new ArgumentNullException(nameof(student));
5
6 return $"{student.FirstName},{student.LastName}";
7 }

优点:nameof 表达式它能够理解成员,当成员被重命名时nameof表达式中也重命名了,而常量字符串表示法是没有这样的优势。

缺点:nameof 表达式生成的是不完全限定名,若你需要完全限定名 nameof 就不能帮你了。

原理解析:nameof 是编译期间就确定其(成员)字符串名称的,即编译后就是常量字符串的表现形式了。

9. 在Catch和Finally中使用Await(Await in Catch and Finally blocks)

C# 5 提供的 async 和 await 使异步编程变得极为简便,但它们也有着局限性:await在catch和finally块中不能使用。但这个问题已在C# 6中得到

了解决,如:

 1   public static async Task<string> MakeRequestAndLogFailures()
2 {
3 await logMethodEntrance();
4 try
5 {
6 // ....
7 var responseText = await streamTask;
8 return responseText;
9 }
10 catch (System.Net.Http.HttpRequestException e) when (e.Message.Contains("301"))
11 {
12 await logError("Recovered from redirect", e);
13 return "Site Moved";
14 }
15 finally
16 {
17 await logMethodExit();
18 }
19 }

10. Index初始化器(Index Initializers)

这个功能并没有什么新意,其实以前就支持集合/字典 初始化器了,如:

 1   var list = new List<string>()
2 {
3 "Mike",
4 "Jim"
5 };
6
7 var dic = new Dictionary<int, string>()
8 {
9 { 20, "Mike" },
10 { 30, "Jim" }
11 };

在C# 6中只是字典初始化器支持了新的写法,如:

1   var dic = new Dictionary<int, string>()
2 {
3 [20] = "Mike",
4 [30] = "Jim"
5 };

总结:暂无发现特殊的用法。

11. 改进的重载解析—编译器(Improved overload resolution)

这算不上是新语法,因为仅仅是编译器的改进,之所以一提是想让大家知道有这么一回事。以前的编译器是识别不了 Task.Run(Func<Task>())

的,如下:

1   static Task DoThings()
2 {
3 return Task.FromResult(0);
4 }
5
6 Task.Run(DoThings); // 此处省略方法代码...

上述代码在老版本编译器下是编译不通过的,而在新版本编译器是能编译通过的。

备注:值得一提的是新版本编译器也只是识别了Task.Run(Func<Task>()),Task.Run(Action) 还是识别不了,总的来说此功能对我们用处不大,

还不如乖乖的写回Lambda表达式。

由于篇幅所限,C# 7 新增的功能就放在下篇介绍......


如果您觉得阅读本文对您有帮助,请点下:"推荐"。^_^

作者:雨夜潇湘QQ群:297829948 
出处:http://www.cnblogs.com/VVStudy/ 

随机推荐

  1. C语言深度剖析-----函数与指针的分析

                          指针的本质 指针需要保证指向任意数据类型,所以指针变量都占用32位bit即4字节. PS:不同机器上,指针占用内存不一                   ...

  2. OC学习篇之---第一个程序HelloWorld

    从这篇开始我们就开始学习OC的相关知识了,在学习之前,个人感觉需要了解的其他的两门语言:一个是C/C++,一个是面向对象的语言(当然C++就是面向对象,不过这里最好还是Java).在干活之前,得先找到 ...

  3. JSP中文件的上传于下载演示样例

    一.文件上传的原理     1.文件上传的前提:         a.form表单的method必须是post         b.form表单的enctype必须是multipart/form-da ...

  4. 结合Wireshark捕获分组深入理解TCP/IP协议之IP协议

    摘要:     本文简单介绍了网络层理论知识,详细讲解了IP数据报各个字段,并从Wireshark俘获分组中选取IP数据报进行分析,也阐述了分组和分片的区别.   一.IPv4数据报     网络层是 ...

  5. like小计

    1.有索引的列最好进行 ‘aa%’形式可以使用一些索引. 2.如果非得进行 ‘%aa%’这种类型查询,那这个条件不要进行主要过滤条件. 意思是这个列如果有索引就不能用索引,即使用了,索引页是进行对整个 ...

  6. ZYNQ7000 LVDS接口输出配置

    xilinx 7系列芯片不再支持LVDS33电平,在VCCO电压为3.3V的情况下无法使用LVDS25接口. 有些设计者想通过在软件中配置为LVDS25,实际供电3.3V来实现LVDS33也是无效的, ...

  7. 黑马day18 jquery高级特性&amp;Ajax的load方法

    介绍jquery中的load方法: (1).前面没有jquery.修饰,能够判断出他是一个普通的非全局函数(也就是说是一个局部函数):$.,$().,jquery.等修饰的就是全局函数.没有这些修饰的 ...

  8. vim修复,telnet安装启动,linux更新软件源

     vim修复: 修复前提,你到UBUNTU能够联网.否则仅仅能卸载,不能安装 1.sudo apt-get remove vim-common 2.sudo apt-get install vim ...

  9. mha && 脚本拉起

    ip分布:  vip 192.168.238.222 mha_manager 192.168.238.131 监控服务器 master 192.168.238.128 主库GTID复制模式 slave ...

  10. ConcurrentHashMap 内部实现分析

    ConcurrentHashMap ConcurrentHashMap是一个线程安全的Hash Table,它的主要功能是提供了一组和HashTable功能相同但是线程安全的方法.Concurrent ...