偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Dotnet 6.0,你值得擁有

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

[[421877]]

本文轉(zhuǎn)載自微信公眾號(hào)「老王Plus」,作者老王Plus的老王。轉(zhuǎn)載本文請(qǐng)聯(lián)系老王Plus公眾號(hào)。

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

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

一、編程語(yǔ)言方面

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

1. 屬性的 required

看一個(gè)簡(jiǎn)單的例子:

  1. public class User 
  2.   public string name { get; set; } 
  3.   public DateTime dateOfBirth { get; set; } 

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

  1. var myUser = new User() 
  2.   name = "WangPlus"

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

而在最新的語(yǔ)言中,對(duì)于這樣的需求,增加了一個(gè) required 屬性。看代碼:

  1. public class User 
  2.   public string name { get; set; } 
  3.   public required DateTime dateOfBirth { get; set; } 

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

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

2. 屬性的 field

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

  1. public class User 
  2.   public string name { get; set; } 
  3.   public DateTime dateOfBirth { get; set; } 

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

  1. public class User 
  2.   public string name { get; set; } 
  3.  
  4.   private DateTime _dateOfBirth; 
  5.   public DateTime dateOfBirth  
  6.   {  
  7.     get 
  8.     { 
  9.       return _dateOfBirth; 
  10.     } 
  11.     set 
  12.     { 
  13.       _dateOfBirth = value.Date
  14.     } 
  15.   } 

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

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

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

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

3. 匿名對(duì)象的 with

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

看代碼:

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

嗯。真的很方便。

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

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

可以想象,如果這個(gè)匿名對(duì)象字段很多的話(huà),就會(huì)麻煩的不要不要的。

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

  1. var myUser1 = myUser with { name = "WangPlus1" }; 

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

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

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

  1. public string FormatName( string name ) 
  2.   if( string.isNullOrEmpty( name ) ) 
  3.     return "ERROR"
  4.   /** ... **/ 
  5. public string FormatUser( User user ) 
  6.   if( user == null ) 
  7.     return "ERROR"
  8.   /** ... **/ 

做法很正確,但很麻煩,一個(gè)套路性的東西,卻要不停的寫(xiě)。

現(xiàn)在,有了一個(gè)神參數(shù):!,沒(méi)錯(cuò),就是嘆號(hào)。

寫(xiě)法是這樣:

  1. public string FormatName( string name! ) 
  2.   /** ... **/ 
  3. public string FormatUser( User user! ) 
  4.     /** ... **/ 

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

5. global using

這是最爽的一個(gè)特性。

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

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

  1. global using System; 
  2. global using System.Collections.Generic; 
  3. global using System.Threading.Tasks; 

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

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

同時(shí),如果已經(jīng)存在 global using,而你的文件中又寫(xiě)了同樣庫(kù)的 using,系統(tǒng)會(huì)扔出一個(gè)警告。

6. 文件級(jí)的命名空間 namespace

這個(gè)特性好像沒(méi)有省了多少事。不過(guò),也算是一個(gè)變化。

以前我們做代碼時(shí),是這樣:

  1. namespace MyNamespace 
  2.     public class User 
  3.     { 
  4.         public void User()   
  5.     { 
  6.             //...Method implementation 
  7.         } 
  8.     } 

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

  1. var obj = new MyNamespace.User(); 
  2. /** 或者 **/ 
  3. using MyNamespace; 
  4. var obj = new User(); 

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

  1. namespace MyNamespace; 
  2. public class User 
  3.   public void User()     
  4.   { 
  5.     //...Method implementation 
  6.   } 

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

二、API方面

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

1. 非流式讀寫(xiě)文件

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

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

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

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

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

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

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

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

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

另外需要注意一下,這個(gè)類(lèi)不在 System 空間下,而在 System.Security.Cryptography 里。

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

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

寫(xiě)法還是我們很熟悉的方式,這個(gè)切換很容易:

  1. var urls = new [] 
  2.   "https://test1.com"
  3.   "https://test2.com" 
  4. }; 
  5. var client = new HttpClient(); 
  6. await Parallel.ForEachAsync(urls, async (url, token) => 
  7.     HttpResponseMessage response = await client.GetAsync(url); 
  8. }); 

4. 定時(shí)中止異步

這也是個(gè)不錯(cuò)的 API。

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

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

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

5. ThrowIfNull

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

  1. public string FormatUser( User user ) 
  2.     ArgumentNullException.ThrowIfNull( user ); 

如果對(duì)象為空,就拋出一個(gè) ArgumentNullException。

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

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

  1. using System.Runtime.InteropServices; 
  2. unsafe 
  3.     byte* buffer = (byte*)NativeMemory.Alloc(128); 
  4.     NativeMemory.Free(buffer); 

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

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

  1. using System.Numerics; 
  2.  
  3. uint bufferSize = 211; 
  4. if (!BitOperations.IsPow2(bufferSize)) 
  5.     bufferSize = BitOperations.RoundUpToPowerOf2(bufferSize); 

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

7. 新的計(jì)時(shí)器

好多文章都把這個(gè)計(jì)時(shí)器稱(chēng)為 Modern Timer,足以可見(jiàn)它的好。

好在哪?這是一個(gè)異步的計(jì)時(shí)器。

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

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

  1. var timer = new PeriodicTimer(TimeSpan.FromSeconds(1)); 
  2. while (await timer.WaitForNextTickAsync()) 
  3.     /** ... **/ 

這個(gè)寫(xiě)法,看著就舒服。

 

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

 

責(zé)任編輯:武曉燕 來(lái)源: 老王Plus
相關(guān)推薦

2023-12-29 08:17:26

Python代碼分析Profile

2021-01-21 09:45:16

Python字符串代碼

2020-12-14 13:32:40

Python進(jìn)度條參數(shù)

2021-07-05 09:40:57

工具Node開(kāi)源

2021-03-18 07:52:42

代碼性能技巧開(kāi)發(fā)

2024-01-04 08:33:11

異步JDK數(shù)據(jù)結(jié)構(gòu)

2014-12-19 10:55:17

Linux性能監(jiān)控

2020-09-01 07:41:56

macOS工具

2024-12-18 16:53:13

ncduLinux磁盤(pán)分析

2021-12-29 07:44:50

Dotnet 代碼系統(tǒng)

2020-10-09 11:54:33

Vue用戶(hù)的React

2020-02-03 12:25:35

Python工具服務(wù)器

2020-06-15 14:43:16

Python開(kāi)發(fā)工具

2022-01-18 16:42:03

區(qū)塊鏈加密信息資源

2020-03-08 13:24:47

JavaScript庫(kù)開(kāi)發(fā)

2011-10-08 10:15:29

Web

2013-07-05 16:08:40

開(kāi)發(fā)效率

2016-07-28 09:37:30

開(kāi)源協(xié)作軟件Collabtive

2013-08-07 09:16:10

云存儲(chǔ)云備份云解決方案

2021-10-06 10:32:07

微軟Windows 11Windows
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)