一:背景
1. 講故事
上一篇跟大家聊到了Target-typed new
和 Lambda discard parameters
,看部落格園和公號裡的閱讀量都達到了新高,甚是欣慰,不管大家對新特性是多頭還是空頭,起碼還是對它抱有一種極為關注的態度,所以我的這個系列還得跟,那就繼續開擼吧,今天繼續帶來兩個新特性,更多新特性列表,請大家關注:新特性預覽
二:新特性研究
1. Native ints
從字面上看貌似是什麼原生型別ints,有點莫名其妙,還是看一看Issues
上舉得例子吧:
Summary: nint i = 1; and nuint i2 = 2;
Shipped in preview in 16.7p1.
有點意思,還是第一次看到有nint這麼個東西,應該就是C#9新增的關鍵詞,好奇心爆棚,快來實操一下。
static void Main(string[] args)
{
nint i = 10;
Console.WriteLine($"i={i}");
}
從圖中看,可以原樣輸出,然後用ILSpy查查底層IL程式碼,發現連IL程式碼都不用看???。如下圖:
從圖中看原來 nint 就是 IntPtr 結構體哈,如果你玩過 C# 到 C++ 之間的互操作,我相信你會對Ptr再熟悉不過了,從這個 nint 上看,你不覺得C#團隊對指標操作是前所未有的重視嗎? 前有指標型別IntPtr
,後有記憶體段處理集合Span
,到現在直接提供關鍵詞支援,就是盡最大努力讓你在型別安全的前提下使用指標。
這就讓我想起了前些天寫的一篇互操作的文章,現在就可以用nint進行簡化了,來段程式碼給大家看一下。
- 原來的寫法:
[DllImport("ConsoleApplication1.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
extern static IntPtr AddPerson(Person person);
static void Main(string[] args)
{
var person = new Person() { username = "dotnetfly", password = "123456" };
var ptr = AddPerson(person);
var str = Marshal.PtrToStringAnsi(ptr);
}
- IntPtr -> nint 的寫法
總的來說這個關鍵詞不是最重要的,重要的是C#團隊對指標操作抱有前所未有的重視,這是一個非常積極的訊號。
2. Pattern matching improvements
模式匹配這個不算是什麼新特性了,在本次C#9中也是繼續得到了完善,可能有很多朋友對模式匹配不是很熟悉,畢竟是C#7才有的新玩法,後面幾乎每一個新版本都在跟蹤完善,我先科普一下吧。
❤ 模式匹配到底解決了什麼問題
大家在編碼的過程中,不可能遇不到 if/else 巢狀 if/else
的這種情況,有時候巢狀甚至達到5,6層之多,特別影響程式碼可讀性,我就來YY個例子。
現在各個地方都在發不同面值的消費券,為了實現千人千面,消費券的發放規則如下:
性別 | 年齡 | 地區 | 面值 |
---|---|---|---|
男 | <20 | 安徽 | 2000 |
男 | <40 | 上海 | 4000 |
男 | 剩餘 | 剩餘 | 3000 |
女 | <20 | 安徽 | 2500 |
女 | <60 | 安徽 | 1500 |
如果用傳統的方式,你肯定要用各種花哨的if/else
來實現,如下程式碼:
static decimal GetTicketFee(string sex, int age, string area)
{
if (sex == "男")
{
if (age < 20 && area == "安徽")
{
return 2000;
}
else
{
if (age < 40 && area == "上海")
{
return 4000;
}
else
{
return 3000;
}
}
}
else
{
if (age < 20 && area == "安徽")
{
return 2500;
}
if (age < 60 && area == "安徽")
{
return 1500;
}
}
return 0;
}
這種程式碼可讀性不是一般的差,就像大強子說的那樣:看著都想打人。。。 問題來了,這程式碼還有救嗎??? 當然有了,這就需要用Pattern matching
去簡化,畢竟它就是為了這種問題而生的,修改後的程式碼如下:
static decimal GetTicketFee_Pattern(string sex, int age, string area)
{
return (sex, age, area) switch
{
("男", < 20, "安徽") => 2000,
("男", < 40, "上海") => 4000,
("男", _, _) => 3000,
("女", < 20, "安徽") => 2500,
("女", < 60, "安徽") => 1500,
_ => 0
};
}
看到這種化簡後的程式碼是不是非常驚訝,這就是 Pattern matching
要幫你解決的場景,接下來看看底層的IL程式碼是什麼樣子。
從圖中看,這反編譯後的程式碼比我手工寫的還要爛,無力吐槽哈,當然 模式匹配
有各種千奇百怪的玩法,絕對讓你瞠目結舌,更多玩法可參考官方文件:模式匹配
這個特性最重要的是你一定要明白它的客戶群在哪裡?
三: 總結
總的來說,這兩個特性都是比較實用的,尤其是 Pattern matching
化解了你多少不得不這麼寫的爛程式碼,頭髮護理就靠它了,快來給它點個贊吧!
好了,先就這樣吧,感謝您的閱讀,希望本篇對你有幫助,謝謝。