日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Dotnet 6.0,你值得拥有

發(fā)布時間:2023/12/4 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Dotnet 6.0,你值得拥有 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Dotnet 6.0 就要來了,這會是一個絕對值得擁有的版本。了解一下?

?

最近在研究 Dotnet 6.0 & C# 10,一個字 - 爽!

下面,分享一下新的一些特性給大家。

一、編程語言方面

編程語言升到 C# 10,新東西不少。

1. 屬性的 required

看一個簡單的例子:

public?class?User {public?string?name?{?get;?set;?}public?DateTime?dateOfBirth?{?get;?set;?} }

假設(shè),我們希望 dateOfBirth 字段必須輸入。在 C# 9.0 之前,其實(shí)我們沒有更好的辦法。比方:

var?myUser?=?new?User() {name?=?"WangPlus", }

這樣寫,編譯器是不會給出任何提醒或警告的。因此,我們需要在各個使用的地方,加上字段賦值的檢查。

?

而在最新的語言中,對于這樣的需求,增加了一個 required 屬性。看代碼:

public?class?User {public?string?name?{?get;?set;?}public?required?DateTime?dateOfBirth?{?get;?set;?} }

這時候,當(dāng)你實(shí)例化 User,而沒有給 dateOfBirth 賦值時,編譯器會直接扔出異常。

在我寫這個文章的同時,剛剛發(fā)現(xiàn)這個特性從最新的 preview 里給移除了,似乎微軟想把這個放到 C# 11中。目前論壇上吵翻了。我們靜待一下結(jié)果。

2. 屬性的 field

在大多數(shù)情況下,我們定義一個類,會采用這種方式:

public?class?User {public?string?name?{?get;?set;?}public?DateTime?dateOfBirth?{?get;?set;?} }

但有時候,因?yàn)橐恍┬枰?#xff0c;需要提前實(shí)例化,或者實(shí)例化時需要進(jìn)行某些處理。比方上面的類,我們只想要 dateOfBirth 的日期部分,我們會把類做成這個樣子:

public?class?User {public?string?name?{?get;?set;?}private?DateTime?_dateOfBirth;public?DateTime?dateOfBirth?{?get{return?_dateOfBirth;}set{_dateOfBirth?=?value.Date;}} }

當(dāng)然,習(xí)慣了也沒什么麻煩的。不過我們知道,_dateOfBirth 這個私有屬性其實(shí)是一個中間數(shù)據(jù),對外沒有用處,但會占用實(shí)例資源。

?

現(xiàn)在,有了一個中間屬性,叫 field。代碼會變成這樣:

public?class?User {public?string?name?{?get;?set;?}public?DateTime?dateOfBirth?{?get;?set?=>?field?=?value.Date;?} }

嗯嗯,可讀性就高了不少。

3. 匿名對象的 with

匿名對象的出現(xiàn),給我們帶來了相當(dāng)多的方便。在類中,不需要對外輸出的結(jié)構(gòu)化數(shù)據(jù),都可以做成匿名對象,而不需要預(yù)先定義一個數(shù)據(jù)對象。

看代碼:

var?myUser?=?new?{?name?=?"WangPlus",?gender?=?"Male"?};

嗯。真的很方便。

不過,也有不方便的地方,就是匿名對象的傳遞。比方,我們想創(chuàng)建另一個對象 myUser1,屬性還是這些,僅僅需要改變幾個屬性的值,怎么辦?在以前,沒有別的辦法,只能重寫一個:

var?myUser1?=?new?{?name?=?"WangPlus1",?gender?=?"Male"?}; /**?或者?**/ var?myUser1?=?new?{?name?=?"WangPlus1",?gender?=?myUser.gender?};

可以想象,如果這個匿名對象字段很多的話,就會麻煩的不要不要的。

?

現(xiàn)在有了 with,這個事情就簡單了:

var?myUser1?=?myUser?with?{?name?=?"WangPlus1"?};

注意,這個寫法,不是把 myUser 里的屬性改了,而是新生成了一個實(shí)例,并傳遞了 myUser 的全部屬性和值到新實(shí)例 myUser1,然后才是把一些屬性的值改成新的值。

4. 非空參數(shù)檢查

在我們寫一個方法時,成熟的程序員,都會做參數(shù)的非空檢查:

public?string?FormatName(?string?name?) {if(?string.isNullOrEmpty(?name?)?)return?"ERROR";/**?...?**/ } public?string?FormatUser(?User?user?) {if(?user?==?null?)return?"ERROR";/**?...?**/ }

做法很正確,但很麻煩,一個套路性的東西,卻要不停的寫。

現(xiàn)在,有了一個神參數(shù):!,沒錯,就是嘆號。

寫法是這樣:

public?string?FormatName(?string?name!?) {/**?...?**/ } public?string?FormatUser(?User?user!?) {/**?...?**/ }

加上 ! 后,執(zhí)行中,程序會自動檢查參數(shù)的非空狀態(tài),如果出現(xiàn) null,會拋出 ArgumentNullExceptions。

5. global using

這是最爽的一個特性。

以前我們寫代碼,每個文件前邊,都有無數(shù)個 using,而且很多 using 都是重復(fù)的。

現(xiàn)在,C# 10 提供了一個 global 關(guān)鍵字。從此,using 變成了:

global?using?System; global?using?System.Collections.Generic; global?using?System.Threading.Tasks;

系統(tǒng)會識別 global using 后邊的內(nèi)容會應(yīng)用于整個項(xiàng)目。因此,在其它文件中,如果需要使用時,可以不寫對應(yīng)的 using ,直接寫代碼即可。

再因此,可以把所有的 global using 放到一個單獨(dú)的文件中,而在其它文件中,不需要再做 using 引用。

同時,如果已經(jīng)存在 global using,而你的文件中又寫了同樣庫的 using,系統(tǒng)會扔出一個警告。

6. 文件級的命名空間 namespace

這個特性好像沒有省了多少事。不過,也算是一個變化。

以前我們做代碼時,是這樣:

namespace?MyNamespace {public?class?User{public?void?User()??{//...Method?implementation}} }

外部調(diào)用時,就這么寫:

var?obj?=?new?MyNamespace.User(); /**?或者?**/ using?MyNamespace; var?obj?=?new?User();

現(xiàn)在,命令空間的定義改成了:

namespace?MyNamespace; public?class?User {public?void?User()????{//...Method?implementation} }

這樣寫,清爽了一些,縮進(jìn)的層次也少了一層。當(dāng)然,調(diào)用還是一樣的。

二、API方面

API 方面就更多了。在社區(qū)里,不停的會有新的 API 爆出來。我就選一些自己感覺有用的來說。

1. 非流式讀寫文件

流式讀寫,經(jīng)常會涉及到中間流,資源浪費(fèi)不說,寫起來也麻煩。

現(xiàn)在可以直接用底層 IO 來讀寫。方法加到了 File 類中。

var?handler?=?File.OpenHandle("abc.txt"); var?length?=?RandomAccess.GetLength(handler);

2. 強(qiáng)隨機(jī)數(shù)

我們知道,以前的隨機(jī)數(shù) Random 類是弱隨機(jī)數(shù),來自于一個算法,并不能做到真正的隨機(jī)。生成的隨機(jī)數(shù)序列取決于種子,相同的種子會產(chǎn)生相同的隨機(jī)數(shù)序列。

所以,為了取到不同的隨機(jī)數(shù)序列,我們一般這么寫:

var?rand?=?new?Random(?(int)DateTime.Now.Ticks?);

當(dāng)然,一般這樣也就夠了。但總有特殊的,需要真正的隨機(jī)數(shù),即強(qiáng)隨機(jī)數(shù)。Dotnet ?6.0 里,提供了一個 RandomNumberGenerator 的類。

byte[]?bytes?=?RandomNumberGenerator.GetBytes(200); int?randomInt?=?RandomNumberGenerator.GetInt32(0,?10000);

另外需要注意一下,這個類不在 System 空間下,而在 System.Security.Cryptography 里。

3. 多任務(wù)的異步 Parallel.ForEachAsync

在多任務(wù)中,以前只有一個 Parallel.ForEach 的方法,用來同步執(zhí)行。這回終于把異步方法 Parallel.ForEachAsync 加進(jìn)來了,足以可見微軟在異步方面的深化決心。

寫法還是我們很熟悉的方式,這個切換很容易:

var?urls?=?new?[] {"https://test1.com","https://test2.com" }; var?client?=?new?HttpClient(); await?Parallel.ForEachAsync(urls,?async?(url,?token)?=> {HttpResponseMessage?response?=?await?client.GetAsync(url); });

4. 定時中止異步

這也是個不錯的 API。

以前當(dāng) await 異步進(jìn)程時,如果這個進(jìn)程長時間結(jié)束不了,我們只能通過 CancellationToken 來結(jié)束。現(xiàn)在,我們有了另一個方式,可以設(shè)置一個時間,以 Timeout 的方式結(jié)束這個異步進(jìn)程。

Task?someTask?=?SomeLongRunningTaskAsync(); await?someTask.WaitAsync(TimeSpan.FromSeconds(10));

如果你寫過 CancellationToken 結(jié)束異步的代碼,就知道這個 WaitAsync 有多好。

5. ThrowIfNull

這個東西,其實(shí)跟上面判斷參數(shù)是否為空是一件事。當(dāng)我們在參數(shù)據(jù)后面加 !來進(jìn)行為空判斷時,實(shí)際就是執(zhí)行的這一句:

public?string?FormatUser(?User?user?) {ArgumentNullException.ThrowIfNull(?user?); }

如果對象為空,就拋出一個 ArgumentNullException。

6. 使用直接內(nèi)存

在以前,使用 unsafe 內(nèi)存 malloc 時,都是在堆上分配空間。現(xiàn)在有了一個在直接內(nèi)存分配空間的方法:

using?System.Runtime.InteropServices; unsafe {byte*?buffer?=?(byte*)NativeMemory.Alloc(128);NativeMemory.Free(buffer); }

做嵌入式開發(fā),有福了。

另外,通常使用非托管內(nèi)容,需要進(jìn)行大小對齊。所謂對齊就是分配的空間的大小需要是 2 的整指數(shù)。通常大家就是算好直接硬寫,現(xiàn)在也有了更靈活的方式:

using?System.Numerics;uint?bufferSize?=?211; if?(!BitOperations.IsPow2(bufferSize)) {bufferSize?=?BitOperations.RoundUpToPowerOf2(bufferSize); }

給一個空間,如果空間大小不是 2 的整指數(shù),就找比這個數(shù)大的 2 的整指數(shù)。又省事了。

7. 新的計時器

好多文章都把這個計時器稱為 Modern Timer,足以可見它的好。

好在哪?這是一個異步的計時器。

以前的計時器 Timer,不管是 System.Timers 下的,還是 System.Threading 下的,或是 System.Windows.Forms 下的,都是同步的計時器,需要用 Tick 的事件綁定來實(shí)現(xiàn)回調(diào)。這個方式讓這個計時器十分依賴上級對象的生命周期,以至于在 UI 編程中,需要用 Invoke 來引入回調(diào)響應(yīng)。

現(xiàn)在這個就簡單很多了:

var?timer?=?new?PeriodicTimer(TimeSpan.FromSeconds(1)); while?(await?timer.WaitForNextTickAsync()) {/**?...?**/ }

這個寫法,看著就舒服。

?

寫了很多,但實(shí)際上,也只是冰山的一小角。

想了解全部的內(nèi)容,可以沒事去泡泡 Dotnet 的社區(qū),每天都有新東西,每天都有驚喜。

喜歡就來個三連,讓更多人因你而受益

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的Dotnet 6.0,你值得拥有的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。