nint
最近看C# 9.0時,發現一個有意思的關鍵詞,就是nint,第一次看到這個,于是好奇心爆棚,就去實際操作了一下。
nint i = 1000;
Console.WriteLine("i={0}", i);
實際結果與int的結果是一樣的,那為什么還要出一個nint關鍵字?這個關鍵字的用途到底在哪里?帶著問題繼續去探索。
對源代碼進行了查看,發現nint是IntPtr的結構體,如果你做過C#與C++之間的交互,我相信你對IntPtr是非常的熟悉,IntPtr是一個指針類型,現在直接提供關鍵詞nint進行支持,讓你能夠在類型安全的前提下使用指針。
IntPtr i = (IntPtr)1000;
Console.WriteLine("i={0}", i);
這樣我就可以對我之前做的關于在C#中進行內存對齊的代碼用nint進行簡化了,代碼如下所示:
public unsafe struct RTCPointQuery8{public fixed float x[8];public fixed float y[8];public fixed float z[8];public fixed float time[8];public fixed float radius[8];}
Span<byte> stack = stackalloc byte[sizeof(RTCPointQuery8) + 32];
ref var test = ref StackAllocAligned<RTCPointQuery8>(stack, 32);static unsafe ref T StackAllocAligned<T>(Span<byte> stack, nuint alignment) where T : unmanaged{return ref Unsafe.AsRef<T>((void*)(((nint)Unsafe.AsPointer(ref MemoryMarshal.GetReference(stack))+ ((nint)alignment - 1)) & ~(nint)(alignment - 1)));}
Pattern matching improvements(模式匹配)
模式匹配是解決if-else嵌套的情形,例如:現在各個地方都在發放消費券,消費券的規則如下:
性別 年齡 地區 面值
男 <20 江蘇 1800
男 <45 上海 3000
男 剩余 剩余 2000
女 <20 浙江 1800
女 <60 浙江 2500
如果使用傳統的方式實現這個過程,你首先想到的是if-else,如下所示:
public static decimal get_ticket(string sex, int age, string district){if(sex == "男"){if(age < 20 && district == "江蘇"){return 1800;}else{if(age < 45 && district == "上海"){return 3000;}else{return 2000;}}}else{if(age < 20 && district == "浙江"){return 1800;}else if(age < 60 && district == "浙江"){return 2500;}}return 0;}
這樣寫倒也是可以的,就是看著不太舒服,if-else太多了,看得眼花繚亂;接下來我們使用模式匹配,看看代碼會是什么樣子,如下所示:
public static decimal get_ticket_pattern(string sex, int age, string distinct){return (sex, age, distinct) switch{("男", < 20, "江蘇") => 1800,("男", < 45, "上海") => 3000,("男", _, _) => 2000,("女", < 20, "浙江") => 1800,("女", < 60, "浙江") => 2500,_ => 0};}
這種簡化后的代碼看著讓人舒服多了,這就是Pattern matching要幫助你解決的場景。
兩者運行的效果是一樣的,如下所示:
但是Pattern matching在轉化成底層代碼之后,也是if-else的模式;玩法有千萬種,絕對讓你瞠目結舌,就看你能不能玩出新的花樣來。當然,這個特性最重要的是你要明白它的客戶群體在哪里?