因為在博客中給出的代碼大多數都使用了C#6.0的新特性,如果各位對C#6.0還不了解,可以簡單的看一下這篇隨筆。o( ̄▽ ̄)d
先來看一個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中的改進
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->同時現在也可以為自動屬性直接設置初值,無需放到構造函數中
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->使用靜態成員
3.1在上面的代碼中看一看到調用Sqrt函數需要使用Math開頭,寫一次兩次還好,如果一個類中大規模使用Sqrt每次都要先寫一個Math會不會太麻煩了!
現在我們來看看如何改進。
首先在命名空間中添加下面這一行代碼
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#團隊辛苦咯!
參考視頻連接