如何利用現(xiàn)代化C#語(yǔ)法簡(jiǎn)化代碼
Intro
最近幾個(gè)版本的 C# 在語(yǔ)法中有很多的變化,有很多語(yǔ)法能夠幫助我們大大簡(jiǎn)化代碼復(fù)雜度,使得代碼更加簡(jiǎn)潔,分享幾個(gè)我覺(jué)得比較實(shí)用的可以讓代碼更加簡(jiǎn)潔的語(yǔ)法
Default literal expressions
在 C# 7.1 之后,我們可以使用 default 來(lái)代替一個(gè)類(lèi)型的默認(rèn)值,例如:
public void Test(string str = deault){} string str = default;
在之前的版本我們需要顯式指定類(lèi)型,如 default(string),就不需要寫(xiě)類(lèi)型了,編譯器會(huì)推斷出類(lèi)型
Target-Typed New Expression
在 C# 9 中,引入了 Target-Typed New Expression 語(yǔ)法,和上面的 default 類(lèi)似,我們?cè)趧?chuàng)建對(duì)象的時(shí)候不再需要在編譯器可以推斷出類(lèi)型的地方再寫(xiě)出類(lèi)型了,這在有時(shí)候會(huì)很有用,尤其是在寫(xiě)一個(gè)類(lèi)型非常復(fù)雜的字段的時(shí)候,我們就只需要聲明一次就可以了,可以參考下面的示例:
// target-typed new expression //private static readonly Dictionary<string, Dictionary<string, string>> // Dictionary = new Dictionary<string, Dictionary<string, string>>(); private static readonly Dictionary<string, Dictionary<string, string>> Dictionary = new(); // array ReviewRequest[] requests = { new() { State = ReviewState.Rejected }, new(), new(), };
Named Tuple
從 C# 7 開(kāi)始,我們可以使用 Named Tuple 來(lái)優(yōu)化 Tuple 的使用,在之前的版本我們只能 Item1, Item2 這樣去使用 Tuple 的 Value,但是這樣很不好理解,尤其是在沒(méi)有文檔說(shuō)明的情況下,可能每次都要去返回值的地方看一下究竟每一個(gè)元素代表什么,Named Tuple 出現(xiàn)了之后就相當(dāng)于一個(gè)強(qiáng)類(lèi)型的 Tuple,能夠使得代碼更好理解,tuple 元素的含義一目了然,舉個(gè)栗子:
(string Alpha, string Beta) namedLetters = ("a", "b"); Console.WriteLine($"{namedLetters.Alpha}, {namedLetters.Beta}"); (int code, string msg) result = (1, ""); private static (int code, string msg) NamedTuple() { return (0, string.Empty); } var result = NamedTuple(); Console.WriteLine(result.code);
Deconstruct
與 Named Tuple 同時(shí)出現(xiàn)的,我們可以在類(lèi)中聲明一個(gè) Deconstruct 與 Constructor 相對(duì)應(yīng),只是 Constructor 是輸入?yún)?shù), Deconstruct 是輸出參數(shù),來(lái)看一個(gè)示例吧:
public class Point { public Point(double x, double y) => (X, Y) = (x, y); public double X { get; } public double Y { get; } public void Deconstruct(out double x, out double y) => (x, y) = (X, Y); } var p = new Point(3.14, 2.71); (double X, double Y) = p;
上面的示例是官方文檔的一個(gè)示例,來(lái)看一個(gè)我們實(shí)際在用的一個(gè)示例吧:
public class IdNameModel { public int Id { get; set; } public string Name { get; set; } public void Deconstruct(out int id, out string name) { id = Id; name = Name; } }
多個(gè)返回值時(shí),有的數(shù)據(jù)不關(guān)心可以使用 “_” 來(lái)表示丟棄返回值,示例如下:
using System; using System.Collections.Generic; public class Example { public static void Main() { var (_, _, _, pop1, _, pop2) = QueryCityDataForYears("New York City", 1960, 2010); Console.WriteLine($"Population change, 1960 to 2010: {pop2 - pop1:N0}"); } private static (string, double, int, int, int, int) QueryCityDataForYears(string name, int year1, int year2) { int population1 = 0, population2 = 0; double area = 0; if (name == "New York City") { area = 468.48; if (year1 == 1960) { population1 = 7781984; } if (year2 == 2010) { population2 = 8175133; } return (name, area, year1, population1, year2, population2); } return ("", 0, 0, 0, 0, 0); } } // The example displays the following output: // Population change, 1960 to 2010: 393,149
Pattern-Matching
模式匹配最早開(kāi)始于 C# 7.1,最早的形式如:if(a is string str),這是最簡(jiǎn)單也是最經(jīng)典的一個(gè)模式匹配,它結(jié)合了之前需要兩句話(huà)才能完成的功能,可以翻譯成:
var str = a as string; if(str != null) //...
除了 if,我們?cè)?switch 里也可以使用模式匹配的
void SwitchPattern(object obj0) { switch (obj0) { case string str1: Console.WriteLine(str1); break; case int num1: Console.WriteLine(num1); break; } }
在 C# 9 中引入了邏輯運(yùn)算符 and/or/not 使得模式匹配更為強(qiáng)大,來(lái)看一個(gè)判斷是否是合法的 Base64 字符的一個(gè)方法的變化:
C# 9 之前的代碼:
private static bool IsInvalid(char value) { var intValue = (int)value; if (intValue >= 48 && intValue <= 57) return false; if (intValue >= 65 && intValue <= 90) return false; if (intValue >= 97 && intValue <= 122) return false; return intValue != 43 && intValue != 47; }
使用 C# 9 增強(qiáng)的模式匹配之后的代碼:
private static bool IsInvalid(char value) { var intValue = (int)value; return intValue switch { >= 48 and <= 57 => false, >= 65 and <= 90 => false, >= 97 and <= 122 => false, _ => intValue != 43 && intValue != 47 }; }
是不是一下子清晰的很多~~
Switch Expression
Switch Expression 是 C# 8 引入的新特性,C# 9 有結(jié)合模式匹配做了進(jìn)一步的增強(qiáng),使得其功能更加強(qiáng)大,來(lái)看示例吧:
修改前的代碼是這樣的:
var state = ReviewState.Rejected; var stateString = string.Empty; switch (state) { case ReviewState.Rejected: stateString = "0"; break; case ReviewState.Reviewed: stateString = "1"; break; case ReviewState.UnReviewed: stateString = "-1"; break; }
使用 switch expression 之后的代碼如下:
var state = ReviewState.Rejected; var stateString = state switch { ReviewState.Rejected => "0", ReviewState.Reviewed => "1", ReviewState.UnReviewed => "-1", _ => string.Empty };
是不是看起來(lái)簡(jiǎn)潔了很多,還有進(jìn)一步的增加優(yōu)化,來(lái)看下一個(gè)示例:
(int code, string msg) result = (0, ""); var res = result switch { (0, _) => "success", (-1, _) => "xx", (-2, "") => "yy", (_, _) => "error" }; Console.WriteLine(res);
猜猜不同情況的輸出的結(jié)果是什么樣的,再自己試著跑一下結(jié)果看看是不是符合預(yù)期吧
Index Range
Index/Range 是 C# 8 引入的一個(gè)新特性,主要優(yōu)化了對(duì)元組的操作,可以更方便的做索引和切片操作
之前有過(guò)一篇詳細(xì)的介紹文章,可以參考:C# 使用 Index 和 Range 簡(jiǎn)化集合操作
我們可以通過(guò) ^(hat) 操作符來(lái)反向索引數(shù)組中的對(duì)象,可以通過(guò) .. 來(lái)創(chuàng)建一個(gè)集合的子集合,來(lái)看一個(gè)簡(jiǎn)單的示例:
var arr = Enumerable.Range(1, 10).ToArray(); Console.WriteLine($"last element:{arr[^1]}"); var subArray = Enumerable.Range(1, 3).ToArray(); Console.WriteLine(arr[..3].SequenceEqual(subArray) ? "StartWith" : "No");
Record
Record 是 C# 9 引入的新特性,record 是一個(gè)特殊的類(lèi),編譯器會(huì)幫助我們做很多事情,會(huì)自動(dòng)實(shí)現(xiàn)一套基于值的比較,而且可以很方便實(shí)現(xiàn)對(duì)象復(fù)制的功能,詳細(xì)介紹可以參考之前的 record 介紹文章 C# 9 新特性 — record 解讀,可以看下面這個(gè)簡(jiǎn)單的示例:
public abstract record Person(string FirstName, string LastName); public record Teacher(string FirstName, string LastName, int Grade) : Person(FirstName, LastName); public record Student(string FirstName, string LastName, int Grade) : Person(FirstName, LastName); public static void Main() { Person teacher = new Teacher("Nancy", "Davolio", 3); Person student = new Student("Nancy", "Davolio", 3); Console.WriteLine(teacher == student); // output: False Student student2 = new Student("Nancy", "Davolio", 3); Console.WriteLine(student2 == student); // output: True }
Top-Level Statement
Top-Level statement 是 C# 9 支持的新特性,我們可以不寫(xiě) Main 方法,直接寫(xiě)方法體,對(duì)于一些比較簡(jiǎn)單的小工具,小測(cè)試應(yīng)用來(lái)說(shuō)會(huì)比較方便
using static System.Console; WriteLine("Hello world");
More
除了上面這些新特性,你覺(jué)得還有哪些比較實(shí)用的新特性呢,歡迎留言一起討論哈~
References
https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9
https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8
https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-7
https://github.com/WeihanLi/SamplesInPractice/blob/master/CSharp9Sample/CleanCodeSample.cs
總結(jié)
到此這篇關(guān)于如何利用現(xiàn)代化C#語(yǔ)法簡(jiǎn)化代碼的文章就介紹到這了,更多相關(guān)C#簡(jiǎn)化代碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C# CancellationToken和CancellationTokenSource的用法詳解
做了.net core之后,發(fā)現(xiàn)CancellationToken用的越來(lái)越平凡了。這也難怪,原來(lái).net framework使用異步的不是很多,而.net core首推異步編程,到處可以看到Task的影子,而CancellationToken正好是異步Task的一個(gè)控制器,所以花點(diǎn)時(shí)間做個(gè)筆記2021-06-06C#實(shí)現(xiàn)窗體中動(dòng)態(tài)按鈕的設(shè)計(jì)方法
在窗體界面中,通常以按鈕來(lái)代替菜單欄的功能,這種形式雖然給用戶(hù)一種直觀(guān)、界面風(fēng)格各異的感覺(jué),但通常按鈕都是以靜止的形式顯示,所以本文給大家介紹了C#實(shí)現(xiàn)窗體中動(dòng)態(tài)按鈕的設(shè)計(jì)方法,感興趣的朋友可以參考下2024-04-04C#實(shí)現(xiàn)JSON和對(duì)象之間互相轉(zhuǎn)換功能示例
這篇文章主要介紹了C#實(shí)現(xiàn)JSON和對(duì)象之間互相轉(zhuǎn)換功能,結(jié)合實(shí)例形式較為詳細(xì)的分析了C#實(shí)現(xiàn)對(duì)象與json之間相互轉(zhuǎn)換的操作技巧,需要的朋友可以參考下2017-09-09基于C#實(shí)現(xiàn)進(jìn)程回收管理工具
這篇文章主要為大家詳細(xì)介紹了入戶(hù)基于C#實(shí)現(xiàn)一個(gè)進(jìn)程回收管理工具,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04C#實(shí)現(xiàn)獲取設(shè)置IP地址小工具
c# 開(kāi)發(fā),方便更改IP地址。由于公司和家里的ip設(shè)置不一樣,公司要求手動(dòng)設(shè)置,在家可以自動(dòng)獲取IP,切都是無(wú)線(xiàn)網(wǎng)絡(luò),為了方便操作,故做了這個(gè)小工具!2015-06-06unity實(shí)現(xiàn)動(dòng)態(tài)排行榜
這篇文章主要為大家詳細(xì)介紹了unity實(shí)現(xiàn)動(dòng)態(tài)排行榜,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07