由于在博客中给出的代码大多数都使用了C#6.0的新特性,若是各位对C#6.0还不了解,能够简单的看一下这篇随笔。o( ̄▽ ̄)djson
先来看一个Point类安全
public class Point { public int X { get; set; } public int Y { get; set; } public Point(int x, int y) { X = x; Y = y; } public double Dist { get { return Math.Sqrt(X * X + Y * Y); } } public override string ToString() { return String.Format("({0}, {1})", X, Y); } }
如今咱们一步步来看在C#6.0中的改进ide
1->在之前版本的C#代码中全部的自动属性都必须有Setter,可是如今能够没有了。注意,不能只有Setter函数
public class Point { public int X { get; } public int Y { get; }
public double Dist { get { return Math.Sqrt(X * X + Y * Y); } } public override string ToString() { return String.Format("({0}, {1})", X, Y); } }
2->同时如今也能够为自动属性直接设置初值,无需放到构造函数中this
public class Point { public int X { get; } = 2; public int Y { get; set; } = 1;
public double Dist { get { return Math.Sqrt(X * X + Y * Y); } } public override string ToString() { return String.Format("({0}, {1})", X, Y); } }
3->使用静态成员spa
3.1在上面的代码中看一看到调用Sqrt函数须要使用Math开头,写一次两次还好,若是一个类中大规模使用Sqrt每次都要先写一个Math会不会太麻烦了!线程
如今咱们来看看如何改进。code
首先在命名空间中添加下面这一行代码orm
using static System.Math;
规则是 using + static + 静态类命名空间视频
因而Dist属性就可改为下面这样
public double Dist { get { return Sqrt(X * X + Y * Y); } }
3.2上面的规则也适用于枚举类型
using static Desktop.Color; namespace Desktop { enum Color { Yellow, Red } class Program { static void Main(string[] args) { Console.WriteLine(Yellow); Console.ReadKey(); } } }
4->关于String.Format()方法的改进
这是经典写法
return String.Format("({0}, {1})", X, Y);
接下来一步步简化(先将String.Format用一个$代替)
return $"({0}, {1})", X, Y);
而后将0,1两个占位符直接换成X,Y
return $"({X}, {Y})";
好的化简完成。
5->对于Lambda表达式的改进
之前写匿名函数的时候能够写成一行,如今通常的函数也能够了
ToString()函数能够改写成以下形式
public override string ToString() => $"({X}, {Y})";
相似的属性能够改为这样
public double Dist => Sqrt(X * X + Y * Y);
注意属性是没有()的
简化后的Point类是这样的
public class Point { public int X { get; } = 2; public int Y { get; set; } = 1;
public double Dist => Sqrt(X * X + Y * Y); public override string ToString() => $"({X}, {Y})"; }
6->索引初始化
先来看一段Json.Net的代码
public JObject ToJson() { var result = new JObject(); result["X"] = X; result["Y"] = Y; return result; }
改进后的代码能够这么写
public JObject ToJson() { var result = new JObject() { ["X"] = X, ["Y"] = Y }; return result; }
最终能够化简成一行代码
public JObject ToJson() => new JObject() { ["X"] = X, ["Y"] = Y };
7-> ?.运算符
?.运算符其实很简单,主要就是检查变量是否为null,若是不为null那就执行.
先来看一个函数,这个判断语句中大部分的检查都是在
public static Point FromJson(JObject json) { if (json != null && json["X"] != null && json["X"].Type == JTokenType.Integer && json["Y"] != null && json["Y"].Type == JTokenType.Integer ) { return new Point((int)json["X"], (int)json["Y"]); } return null; }
这个函数能够用?.运算符化简成
public static Point FromJson(JObject json) { if (json != null && json["X"]?.Type == JTokenType.Integer && json["Y"]?.Type == JTokenType.Integer ) { return new Point((int)json["X"], (int)json["Y"]); } return null; }
若是json["x"]为null,那么就不执行. 若是json["x"]不为null,那么就会执行.而后判断类型是否为int
因此代码能够被再次化简
public static Point FromJson(JObject json) { if (json?["X"]?.Type == JTokenType.Integer && json?["Y"]?.Type == JTokenType.Integer ) { return new Point((int)json["X"], (int)json["Y"]); } return null; }
?.还有一个比较大的用处在触发事件的时候
OnChanged(this, args);
若是此时OnChanged为空显然是不行的因此呢,能够改写成这样
if (OnChanged == null) { OnChanged(this, args); }
若是很不幸的另一个线程就在判断以后,触发事件以前,再次设置OnChanged变为null,一样会致使错误
为了保证线程安全
须要先Copy一份,可是这样写显然就。。。
var onChanged = OnChanged; if (onChanged != null) { onChanged(this, args); }
如今能够改写成这样
OnChanged?.(this, args);
8-> 支持在catch和finally块中使用await
好滴以上就是C#6.0的一些新特性,这些改进我的感受仍是很是实用的!C#团队辛苦咯!