先注明,本文主体参考自:C# 6.0新特性

目前代码中使用了很多C#6.0的新特性,下面以Point类来做相关叙述:

  1. public class Point
  2. {
  3. public int X { get; set; }
  4.  
  5. public int Y { get; set; }
  6.  
  7. public Point(int x, int y)
  8. {
  9. X = x;
  10. Y = y;
  11. }
  12.  
  13. public double Dist
  14. {
  15. get { return Math.Sqrt(X * X + Y * Y); }
  16. }
  17.  
  18. public override string ToString()
  19. {
  20. return String.Format("({0}, {1})", X, Y);
  21. }
  22. }

现在我们一步步来看在C#6.0中的改进

1->在以前版本的C#代码中所有的自动属性都必须有Setter,但是现在可以没有了。注意,不能只有Setter

  1. public class Point
  2. {
  3. public int X { get; }
  4.  
  5. public int Y { get; }
  6.  
  7.      public double Dist
  8. {
  9. get { return Math.Sqrt(X * X + Y * Y); }
  10. }
  11.  
  12. public override string ToString()
  13. {
  14. return String.Format("({0}, {1})", X, Y);
  15. }
  16. }

2->同时现在也可以为自动属性直接设置初值,无需放到构造函数中

  1. public class Point
  2. {
  3. public int X { get; } = 2;
  4.  
  5. public int Y { get; set; } = 1;
  6.  
  7.      public double Dist
  8. {
  9. get { return Math.Sqrt(X * X + Y * Y); }
  10. }
  11.  
  12. public override string ToString()
  13. {
  14. return String.Format("({0}, {1})", X, Y);
  15. }
  16. }

3->使用静态成员

  3.1在上面的代码中看一看到调用Sqrt函数需要使用Math开头,写一次两次还好,如果一个类中大规模使用Sqrt每次都要先写一个Math会不会太麻烦了!

现在我们来看看如何改进。

首先在命名空间中添加下面这一行代码

  1. using static System.Math;

规则是 using + static + 静态类命名空间

于是Dist属性就可改成下面这样

  1. public double Dist
  2. {
  3. get { return Sqrt(X * X + Y * Y); }
  4. }

  3.2上面的规则也适用于枚举类型

  1. using static Desktop.Color;
  2.  
  3. namespace Desktop
  4. {
  5. enum Color
  6. {
  7. Yellow,
  8. Red
  9. }
  10.  
  11. class Program
  12. {
  13. static void Main(string[] args)
  14. {
  15. Console.WriteLine(Yellow);
  16. Console.ReadKey();
  17. }
  18. }
  19. }

4->关于String.Format()方法的改进

这是经典写法

  1. return String.Format("({0}, {1})", X, Y);

接下来一步步简化(先将String.Format用一个$代替)

  1. return $"({0}, {1})", X, Y);

然后将0,1两个占位符直接换成X,Y

  1. return $"({X}, {Y})";

好的化简完成。

5->对于Lambda表达式的改进

以前写匿名函数的时候可以写成一行,现在一般的函数也可以了

ToString()函数可以改写成如下形式

  1. public override string ToString() => $"({X}, {Y})";

类似的属性可以改成这样

  1. public double Dist => Sqrt(X * X + Y * Y);

注意属性是没有()的

简化后的Point类是这样的

  1. public class Point
  2. {
  3. public int X { get; } = 2;
  4.  
  5. public int Y { get; set; } = 1;
  6.  
  7. public double Dist => Sqrt(X * X + Y * Y);
  8.  
  9. public override string ToString() => $"({X}, {Y})";
  10. }

6->索引初始化

先来看一段Json.Net的代码

  1. public JObject ToJson()
  2. {
  3. var result = new JObject();
  4. result["X"] = X;
  5. result["Y"] = Y;
  6. return result;
  7. }

改进后的代码可以这么写

  1. public JObject ToJson()
  2. {
  3. var result = new JObject()
  4. {
  5. ["X"] = X,
  6. ["Y"] = Y
  7. };
  8. return result;
  9. }

最终可以化简成一行代码

  1. public JObject ToJson() => new JObject() { ["X"] = X, ["Y"] = Y };

7-> ?.运算符

?.运算符其实很简单,主要就是检查变量是否为null,如果不为null那就执行.

先来看一个函数,这个判断语句中大部分的检查都是在

  1. public static Point FromJson(JObject json)
  2. {
  3. if (json != null &&
  4. json["X"] != null &&
  5. json["X"].Type == JTokenType.Integer &&
  6. json["Y"] != null &&
  7. json["Y"].Type == JTokenType.Integer
  8. )
  9. {
  10. return new Point((int)json["X"], (int)json["Y"]);
  11. }
  12. return null;
  13. }

这个函数可以用?.运算符化简成

  1. public static Point FromJson(JObject json)
  2. {
  3. if (json != null &&
  4. json["X"]?.Type == JTokenType.Integer &&
  5. json["Y"]?.Type == JTokenType.Integer
  6. )
  7. {
  8. return new Point((int)json["X"], (int)json["Y"]);
  9. }
  10. return null;
  11. }

如果json["x"]为null,那么就不执行. 如果json["x"]不为null,那么就会执行.然后判断类型是否为int

所以代码可以被再次化简

  1. public static Point FromJson(JObject json)
  2. {
  3. if (json?["X"]?.Type == JTokenType.Integer &&
  4. json?["Y"]?.Type == JTokenType.Integer
  5. )
  6. {
  7. return new Point((int)json["X"], (int)json["Y"]);
  8. }
  9. return null;
  10. }

?.还有一个比较大的用处在触发事件的时候

  1. OnChanged(this, args);

如果此时OnChanged为空显然是不行的所以呢,可以改写成这样

  1. if (OnChanged == null)
  2. {
  3. OnChanged(this, args);
  4. }

如果很不幸的另外一个线程就在判断之后,触发事件之前,再次设置OnChanged变为null,同样会导致错误

为了保证线程安全【可参考多线程下C#如何保证线程安全?

需要先Copy一份,但是这样写显然就。。。

  1. var onChanged = OnChanged;
  2. if (onChanged != null)
  3. {
  4. onChanged(this, args);
  5. }

注:var onChanged = OnChanged;就是为了防止OnChanged被其它线程置为空。

现在可以改写成这样

  1. OnChanged?.(this, args);

8-> 支持在catch和finally块中使用await

C# Note33: 总结C# 6.0/7.0 新特性的更多相关文章

  1. 有史来最大改变 Android 5.0十大新特性

    有史来最大改变 Android 5.0十大新特性 2014.10.16 14:51:31 来源:腾讯数码作者:腾讯数码 ( 0 条评论 )   距离Android系统上一次重大更新不到一年的时间,谷歌 ...

  2. C# 6.0可能的新特性及C#发展历程

    据扯,C# 6.0在不远的将来就发布了,对应的IDE可能是VS 2014(.Net Framework 5.0),因为VS 2013已于2013年10月份发布了,对应的是.Net Franework ...

  3. C# 6.0可能的新特性

    C# 6.0可能的新特性 1.主构造函数(Primary Constructors) 主构造函数给类中的变量赋值 Before public class Point { private int x, ...

  4. Spring Boot 2.0正式发布,新特性解读

    作者|翟永超 Spring Boot 2.0 来啦,有哪些新特性?升级吗? 写在前面 北京时间 3 月 1 日,经过漫长的等待之后,Spring Boot 2.0 正式发布.作为 Spring 生态中 ...

  5. C# 6.0可能的新特性及C#发展历程[转]

      C# 6.0可能的新特性及C#发展历程[转] 年10月份发布了,对应的是.Net Franework 4.5.1. 或者3年,更新增加的东西会比较多,所以对于C# 6.0,还是有一些期待的. 下面 ...

  6. MySQL 8.0.2复制新特性(翻译)

    译者:知数堂星耀队 MySQL 8.0.2复制新特性 MySQL 8 正在变得原来越好,而且这也在我们MySQL复制研发团队引起了一阵热潮.我们一直致力于全面提升MySQL复制,通过引入新的和一些有趣 ...

  7. Atitit.c# .net 3.5 4.0 4.5 5.0 6.0各个版本新特性战略规划总结

    Atitit.c# .net 3.5 4.0 各个版本新特性战略规划总结 1. --------------.Net Framework版本同CLR版本的关系1 2. paip.----------- ...

  8. c# .net 3.5 4.0 4.5 5.0 6.0各个版本新特性战略规划总结【转载】

    引用:http://blog.csdn.net/attilax/article/details/42014327 c# .net 3.5 4.0 各个版本新特性战略规划总结 1. ---------- ...

  9. 转载——C# 6.0可能的新特性及C#发展历程

    据扯,C# 6.0在不远的将来就发布了,对应的IDE可能是VS 2014(.Net Framework 5.0),因为VS 2013已于2013年10月份发布了,对应的是.Net Franework ...

  10. 【HANA系列】SAP HANA 1.0 SPS 11 新特性

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA 1.0 SPS ...

随机推荐

  1. python六十九课——网络编程之TCP协议

    1.1 概述: TCP协议通过三次握手协议将客户端与服务器端连接,两端使用各自的Socket对象.Socket对象中包含了IO流,供数据传输. 即:TCP协议在客户端与服务器端通过Socket组成了I ...

  2. 单片机与android手机通信(控制LED小灯亮灭)

    1.单片机实验板功能设计 为验证数据通信内容,让单片机板上的四个按键与android手机客户端上的四个LED灯相互控制:为达到上述基本实验要求,采用单字符传输数据即可,硬件需设计两块相同的单片机电路板 ...

  3. y7000笔记本 darknet-yolo安装与测试(Ubuntu18.04+Cuda9.0+Cudnn7.1)

    环境配置看上一贴 https://www.cnblogs.com/clemente/p/10386479.html 1 安装darknet 1-1 克隆darknet repo git clone h ...

  4. .Net使用RabbitMQ详解 转载http://www.cnblogs.com/knowledgesea/p/5296008.html

    .Net使用RabbitMQ详解   序言 这里原来有一句话,触犯啦天条,被阉割!!!! 首先不去讨论我的日志组件怎么样.因为有些日志需要走网络,有的又不需要走网路,也是有性能与业务场景的多般变化在其 ...

  5. NOIP2018初赛游记

    NOIP2018初赛游记 (编辑中)

  6. reedis 解决在windows下启动闪退

    windows下安装https://github.com/MicrosoftArchive/redis/releases第一次启动报错: [2368] 21 Apr 02:57:05.611 # Cr ...

  7. "INSTALL_FAILED_DUPLICATE_PERMISSION "错误解决

    我们在进行Android组件安全测试时,如果遇到声明了权限的组件,在编写PoC时,可能会遇到如下错误提示: INSTALL_FAILED_DUPLICATE_PERMISSION perm=com.m ...

  8. Luogu P4205 [NOI2005]智慧珠游戏

    国内少有的可以练习神仙算法--DLX的好题怎么可以被爆搜埋没呢? 看到这题没有DLX的题解所以写一篇,不过貌似我实现的太弱(构图太慢)所以速度上不是很快. 下面开始讲题,但请保证你要先学会DLX.(d ...

  9. 使用Python的http.server实现一个简易的Web Api对外提供HanLP拼音转换服务

    由于采集省市区镇数据需要对地名进行拼音转换,由于第三方高准确度接口对IP进行了限制,处理大量数据变得异常缓慢. 使用了一个折中的办法,省市区 3级(3千+)用高准确度接口(几乎没有拼错的地名),镇级( ...

  10. 并发连接MySQL

    先吐槽一下libmysqlclientAPI的设计, 多个线程同时去connect居然会core掉. 后来Google了一番, 才发现mysql_real_connect不是线程安全的, 需要一些额外 ...