最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

C# 10 特性一覽

2021-03-02 17:59 作者:SunnieShine  | 我要投稿

C# 官方團(tuán)隊(duì)最近正在研究下一個(gè)版本(C# 10)的新特性。下面我們來看一下。以后做 C# 教程視頻的時(shí)候,看情況,如果錄制到這個(gè)地方的時(shí)候,C# 10 特性發(fā)布正式版本的時(shí)候,說不定我還會(huì)單獨(dú)錄一個(gè)視頻。這里先做一個(gè)參考。

Part 1 結(jié)構(gòu)記錄類型

C# 9 有一個(gè)新的數(shù)據(jù)類型,叫做記錄(Record)。這個(gè)類型是一種特殊的引用類型,我們只需要給出一個(gè)東西的具體屬性,就可以自動(dòng)為這個(gè)類型生成指定的比較器(Equals 方法、比較運(yùn)算符 operator ==operator !=、GetHashCode 方法,甚至是 ToString 方法等等)。

舉個(gè)例子,我們可以這么寫:

這就等價(jià)于一個(gè)類 Point,然后生成 XY 屬性,以及相關(guān)的方法:

這樣的東西。你看看,就寫一句話就能生成一系列的內(nèi)容,是不是很方便。

不過,Point 類型就倆屬性,顯然沒有必要定義成類,因?yàn)樗p量級(jí)了。因此,C# 10 開始允許結(jié)構(gòu)記錄類型。

這樣就好比把前文的 sealed class 改寫成 struct。因此 C# 10 開始允許結(jié)構(gòu)的記錄類型,所以更輕量級(jí),靈活度更高了。當(dāng)然,C# 10 依然允許引用類型(類)的記錄類型,你可以使用 record 或者 record class 來表示一個(gè)類的記錄類型。

前文用到的 init 屬性是 C# 9 里誕生的、用來表示屬性只在初始化器和構(gòu)造器里才可賦值的一種屬性賦值模型。它比 set 的使用范圍要少,set 隨時(shí)隨地都可以賦值(最多加一個(gè)訪問修飾符,但并不能阻止內(nèi)部的任何時(shí)候的賦值)。init 僅允許初始化器和構(gòu)造器里使用賦值,其它任何地方都不能賦值。這樣做就避免了很多地方的安全問題,同時(shí)也提供了一種語法上的約束。

Part 2 全局 using 指令

C# 很早(C# 2)就允許類型取別名。但由于這個(gè)東西實(shí)在是不好用(只允許同文件取別名),因此不是很常用。C# 10 開始允許全局的 using 指令。

你只需要在單獨(dú)的文件里寫上這么一句話:

global using IntegerList = System.Collections.Generic<int>;

那么,整個(gè)項(xiàng)目就都可以使用這個(gè) IntegerList 了。

Part 3 namespace 指令

C# 團(tuán)隊(duì)是真的有趣,這種沒有啥特殊意義的特性也開始允許了。但是說實(shí)話,如果允許了的話,其實(shí)還是挺不錯(cuò)的一個(gè)東西,畢竟縮進(jìn)也變少了,這樣代碼的層次就分得比較清楚了。

在 C# 10 里,你可以使用一句類似 using 指令的形式,對(duì)文件整體進(jìn)行聲明命名空間,這樣的話,后續(xù)的內(nèi)容就不用再用大括號(hào)了:

這樣就等價(jià)于經(jīng)典寫法:

果然,少了括號(hào)就是好。但是,原始的寫法是允許嵌套命名空間和并排命名空間的,而一旦使用 namespace 指令后,就不可在文件里多次聲明嵌套或并行的命名空間了。換句話說,這種寫法僅僅是一個(gè)語法糖。

Part 4 內(nèi)插字符串?dāng)U展

該特性實(shí)際上有兩個(gè)小的子特性。下面我們來說下。

Part 4-1 推廣到集合類型的 params 參數(shù)

在早期的 C#,params 參數(shù)后的參數(shù)類型必須是數(shù)組。由于數(shù)組本身比較笨重的緣故(是引用類型),所以就很不利于擴(kuò)展性能。因此,C# 10 開始允許用戶使用 params 集合 的模式來聲明參數(shù)。比如說

如例子所示,我們?cè)试S參數(shù)使用 params Span<string> 這樣的東西,就可以對(duì)字符串進(jìn)行一些操作,還可以使用變長(zhǎng)參數(shù)的模型,因此相當(dāng)方便且有可讀性。

目前,C# 團(tuán)隊(duì)打算允許如下一些集合類型作為 params 的依托:

  • params T[](經(jīng)典寫法)

  • params IEnumerable<T>

  • params Span<T>

  • params ReadOnlySpan<T>

另外,按照次序,如果有這樣四個(gè)方法的重載的話,C# 會(huì)優(yōu)先采用效率高的 ReadOnlySpan<T> 類型作為調(diào)用方,然后是 Span<T>、T[],最后才是 IEnumerable<T>。

其實(shí)也很好記。ReadOnlySpan<T>Span<T> 一定是效率最高的,因?yàn)樗鼈儍H存儲(chǔ)在棧內(nèi)存里;但是,ReadOnlySpan<T> 不可變,所以相較于后者來說,它更為安全;接著,T[]IEnumerable<T> 里,顯然是數(shù)組更好用,然后才是迭代集合 IEnumerable<T>,因?yàn)榈弦褂煤軓?fù)雜的迭代器模式來迭代,是一種耗費(fèi)性能較高的類型;但為了可讀性,C# 依舊允許了這一個(gè)類型作為 params 參數(shù)。

Part 4-2 更高效、不裝箱拆箱的內(nèi)插字符串

在允許了前文給的特性后,內(nèi)插字符串就可以使用更為高級(jí)的語法,來避免裝箱和拆箱了。在 C# 6 里,內(nèi)插字符串會(huì)被自動(dòng)翻譯為 string.Format 的調(diào)用。而很遺憾的是,這個(gè)方法的參數(shù)都是 object 類型的可變參數(shù)序列,因而值類型在傳入的時(shí)候必然導(dǎo)致裝箱,損失了性能。在允許了 4-1 特性后,string.Format 就有了新的實(shí)現(xiàn)方式:

這里的 Variant 類型在 C# 團(tuán)隊(duì)實(shí)現(xiàn)后才會(huì)給出。這里你可以理解成一個(gè)“任何類型都可以兼容的值類型”。換句話說,任何類型都可以轉(zhuǎn)這個(gè)類型來存儲(chǔ),類似 object,只是這里用 Variant 表達(dá)出來可以避免裝箱(因?yàn)槭侵殿愋停?;至于引用類型,傳過來就會(huì)被改成地址什么的,總之不會(huì)裝箱就對(duì)了。

其它的問題和解答,你可以查看這篇文檔(英文原文檔)。

Part 5 無參值類型構(gòu)造器

C# 一直以來就存在一個(gè)備受爭(zhēng)議的語法點(diǎn):值類型的無參構(gòu)造器到底是否有必要禁止用戶自己聲明。C# 團(tuán)隊(duì)是這么想的:由于值類型是作為基本數(shù)據(jù)類型的實(shí)現(xiàn)體現(xiàn)(比如 int 這些數(shù)據(jù)類型),那么它們必然就有賦值和構(gòu)造的默認(rèn)權(quán)力。如果給用戶用的話,用戶就有可能會(huì)誤用無參構(gòu)造器,導(dǎo)致初始化的問題。因此,C# 的引用類型和值類型的無參構(gòu)造器表現(xiàn)的行為不同:值類型的是永久都存在的,且你無法自己定義;而引用類型的無參構(gòu)造器在沒有構(gòu)造器的類里會(huì)自動(dòng)生成,有構(gòu)造器的話,就不會(huì)自動(dòng)生成,需要你自己定義。

那么,C# 團(tuán)隊(duì)考慮了很久,終于想通了。用戶開始可以自己定義無參構(gòu)造器了。

Part 5-1 真·無參構(gòu)造器

如代碼所示。

這個(gè)例子展示了無參構(gòu)造器的使用方式。顯然,跟引用類型是基本一樣的,只是多了一點(diǎn):如果你不定義的話,默認(rèn)會(huì)生成一個(gè)無參構(gòu)造器(S0 結(jié)構(gòu),y 會(huì)被自動(dòng)賦值默認(rèn)數(shù)值 default(object),也就是 null);但一經(jīng)定義,就必須給所有沒有賦值的字段和屬性賦值。

當(dāng)然,此時(shí)的構(gòu)造器既然允許自定義了,這樣就使得構(gòu)造器可以定義和修改訪問修飾符了。如果訪問修飾符設(shè)置為 private 的話,那么外部就無法使用 new 來實(shí)例化該類型的對(duì)象了。這一點(diǎn)和引用類型還是一樣的。

Part 5-2 結(jié)構(gòu)的字段初始化器

可以看到,這個(gè)特性一旦出現(xiàn),就相當(dāng)于誕生了另外一個(gè)特性:結(jié)構(gòu)的字段初始化器。C# 早期同樣是不允許你給字段設(shè)置默認(rèn)數(shù)值的;相反,你必須在構(gòu)造器里賦值,還不能是默認(rèn)的無參構(gòu)造器里。

Part 5-3 default(T) 表達(dá)式

另外,由于值類型和引用類型的默認(rèn)數(shù)值不同的關(guān)系,定義了無參構(gòu)造器必然會(huì)影響到它的默認(rèn)數(shù)值 default(T) 表達(dá)式。實(shí)際上真的是這樣嗎?并不是。還是拿 Point 類型舉例。即使你給出了默認(rèn)構(gòu)造器的調(diào)用,default(Point) 依舊還是原始數(shù)據(jù)的原始數(shù)據(jù)類型的默認(rèn)數(shù)值構(gòu)造成的實(shí)例的結(jié)果。

那么,default(Point) 還是 Point { X = 0, Y = 0 },而不是 Point { X = -2147483647, Y = -2147483647 } 的這個(gè)新結(jié)果。

我們把“原始數(shù)據(jù)的原始數(shù)據(jù)類型的默認(rèn)數(shù)值構(gòu)造成的實(shí)例”叫做零初始化實(shí)例(Zeroed Instance),那么,default(T) 的定義就可以縮減為“該類型的零初始化實(shí)例”;換句話說,該類型的零初始化實(shí)例就是這個(gè)值類型的默認(rèn)數(shù)值。那么,使用 default 表達(dá)式的時(shí)候,就算你定義了無參構(gòu)造器,編譯器也會(huì)始終忽略它。

Part 6 參數(shù)的 nameof 表達(dá)式

我們經(jīng)常會(huì)考慮到這樣的使用場(chǎng)合:

由于特性在方法外部,因此無法直接使用 obj 這個(gè)名稱。傳入字符串有時(shí)候依然不方便,因?yàn)槟阈薷牧?obj 的名字之后,上方特性傳入的 "obj" 并未進(jìn)行修改,就會(huì)產(chǎn)生隱藏的 bug。因此,C# 10 開始允許我們使用參數(shù),來避免這一點(diǎn)。

這樣就很方便了。

Part 7 增強(qiáng)對(duì)是否為 null 的對(duì)象的代碼分析

C# 8 誕生了可空引用類型的概念,并提供了基本的分析模型。但很遺憾的是,很多時(shí)候,編譯器依舊無法識(shí)別對(duì)象已經(jīng)不可能是 null 的情況,進(jìn)而產(chǎn)生語義分析上的 bug。C# 10 提出了增強(qiáng)分析的概念,這樣的話,很多原本是 bug 的情況就得到了解決。舉個(gè)例子。

比如這個(gè)例子下,c 不可空后,調(diào)用 M 方法后,如果返回值為 true 的話,參數(shù) obj1 就不能為空了。而編譯器暫時(shí)無法識(shí)別這種變量的傳遞(最開始是從 c != null 開始的),因此分析這個(gè)地方的時(shí)候,obj1 仍然不知道是不是為 null。

C# 10 會(huì)對(duì)這樣類似的場(chǎng)景的分析進(jìn)行修復(fù)。

順帶凡爾賽一波,我提了一個(gè)屬于這個(gè)特性主題的 issue,它們也放在了這個(gè)提案里作為解決對(duì)象。

Part 8 refpartial 關(guān)鍵字的順序

在誕生了 ref struct 這種類型之后,C# 由于沒有考慮到語法的靈活性,因此如果 ref struct 是分部類型的話,就必須寫成 ref partial struct,而調(diào)轉(zhuǎn)順序 partial ref struct 則是錯(cuò)誤的寫法。

C# 10 將對(duì)這個(gè)問題進(jìn)行修復(fù)。

Part 9 參數(shù)可空性驗(yàn)證

Part 9-1 可空校驗(yàn)標(biāo)記符 !!

如果一個(gè)參數(shù)為 null,我們期望使用 throw 語句來產(chǎn)生異常信息。于是,代碼大概就長(zhǎng)這樣:

C# 10 將允許我們直接添加雙嘆號(hào)到 str 參數(shù)聲明上,這樣的話,if 和異常拋出的語句就可以不寫了。

Part 9-2 對(duì)于值類型和可空引用類型的可空校驗(yàn)

當(dāng)然,這個(gè)特性用在如果你沒有對(duì)項(xiàng)目啟用 nullable enable 的地方。因?yàn)槲覀兡馨汛a寫成 string? arg!! 就沒有必要為類型追加這個(gè)冗余的可空標(biāo)記符號(hào) ?。既然對(duì)象一旦為空就拋異常,那么我們何必寫成 string? 呢?寫成 string 不好嗎?你說是吧。

另外,值類型本身就不可能為 null 了,我們何從談起對(duì)值類型使用 !! 呢?當(dāng)然了,Nullable<T> 除外。不過,對(duì)可空值類型使用 !! 的話,還不如不用可空值類型,直接不讓它可空不就行了。

所以,總的來說,只要是對(duì)可空類型(包含值類型、引用類型這兩種)使用 !! 的話,編譯器都會(huì)產(chǎn)生警告,然后提示你“沒必要這么用”。

Part 10 調(diào)用方表達(dá)式特性

在 C# 5 的時(shí)候,誕生了調(diào)用方參數(shù)特性。我們可以使用可選參數(shù)配合 CallerMemberNameAttribute 等特性標(biāo)記到參數(shù)上面,這樣的話,運(yùn)行時(shí)就會(huì)自動(dòng)把該數(shù)據(jù)傳入到這個(gè)參數(shù)上去(比如 CallerMemberNameAttribute 會(huì)把調(diào)用方方法名傳過來)。

現(xiàn)在,C# 10 里新增一個(gè)調(diào)用方表達(dá)式特性,這樣的話,就可以把參數(shù)上的表達(dá)式傳過來了。

Part 11 泛型特性

我們目前用到了很多需要傳入一個(gè)或多個(gè) Type 類型的特性,但是很顯然,這樣傳入進(jìn)去有一個(gè)比較麻煩的地方:特性里的參數(shù)無法確定類型,就會(huì)導(dǎo)致裝箱和拆箱操作。

C# 10 里允許泛型特性的支持,我們就可以使用這樣的語法傳入一個(gè)泛型,帶一個(gè)類型的方式,就不必再考慮這種性能問題了。

這樣就比起經(jīng)典寫法 [DebuggerProxy(typeof(ComplexValueDebuggerProxy))] 要好看不少。而且,特性里的屬性就可以直接使用泛型參數(shù)替換 object 來表達(dá)了,確實(shí)很方便。

Part 12 解構(gòu) default 表達(dá)式

如果我們有這么一句話在 C# 里是允許的話:

你覺得,arg1arg2 會(huì)是多少呢?C# 10 里將允許這個(gè)寫法,這樣的話,arg1arg2 就會(huì)默認(rèn)賦值 0。

Part 13 內(nèi)插字符串常量

C# 6 誕生的內(nèi)插字符串并不能直接當(dāng)成常量使用。舉個(gè)例子:

這個(gè)寫法對(duì)嗎?從道理上是說得通的。但是,這個(gè)寫法不對(duì)。因?yàn)閮?nèi)插字符串沒有得到編譯器認(rèn)為其是常量的允許,因此 B 這里會(huì)產(chǎn)生編譯器錯(cuò)誤。所以,你不得不改成加法運(yùn)算。

C# 10 開始允許這一點(diǎn),內(nèi)插字符串也可以認(rèn)為是常量了;當(dāng)然前提是,內(nèi)插的部分也都得是常量才行;而且內(nèi)插的對(duì)象必須也得是 string 才行。

Part 14 元組表達(dá)式里內(nèi)聯(lián)變量定義

這句話不好理解。舉個(gè)例子。

假如,name 是本身就有的東西(它可能是屬性,或者是字段,或者是臨時(shí)變量),而 age 僅僅是一個(gè)臨時(shí)變量。如果你要把右側(cè)的 student 變量解構(gòu)了的話,由于 age 的定義變量語句無法寫到賦值語句里面去,所以只能分開成兩行書寫。

C# 10 將允許你內(nèi)嵌定義語句到值元組賦值的語句里去。

這樣就合二為一了。name 照舊賦值,而 age 則完成了定義變量和賦值兩個(gè)操作,且都在這一行里就可以完成。方便了不少。

Part 15 模式匹配 IV:集合模式

從 C# 7 開始,模式匹配就是一種特別高大上的語法,搞得別的編程語言紛紛效仿。C# 7 里允許了在 switch 語句里使用 when 從句,并同時(shí)允許了 is 表達(dá)式里內(nèi)聯(lián)變量定義;C# 8 里允許了遞歸模式匹配;C# 9 里則又多了 andnotor 的邏輯模式匹配。C# 10 這次帶來的是集合模式匹配。

集合模式匹配可以對(duì)集合的元素進(jìn)行解構(gòu)、處理和判別。

Part 15-1 長(zhǎng)度模式

長(zhǎng)度模式聽起來好像是在判斷集合的長(zhǎng)度,但是這一點(diǎn)不是可以用 Length 屬性的遞歸模式作為判斷對(duì)象嗎?是的,長(zhǎng)度模式并不是這個(gè)意思。

長(zhǎng)度模式用中括號(hào)來獲取數(shù)據(jù)元素,然后通過冒號(hào)和模式來表達(dá)一個(gè)對(duì)象的指定索引位置上的數(shù)據(jù)是不是滿足這個(gè)模式。舉個(gè)例子:

當(dāng) arr 必須是帶 LengthCount 屬性的類型,且擁有一個(gè)以 int 類型作為參數(shù)的索引器時(shí)候,就可以用這個(gè)模式寫法。這句話表示,當(dāng) arr 數(shù)據(jù)的第 3 個(gè)元素是一個(gè)整數(shù),且不是 -1 的時(shí)候,滿足條件。

如果 arr 在這里不能確定和斷定是不是包含 LengthCount 屬性,或者是 int 類型作參數(shù)的索引器的時(shí)候,那么編譯器就會(huì)告訴你,arr 由于無法斷定類型,所以無法使用該模式來對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)。

上方語法等價(jià)于 arr[2] is int val && val != -1。你可能不一定能理解,為什么 arr[2] is int val 這句話要寫出來。因?yàn)?arr 的元素類型尚不清楚,換句話說就是,arr 可能是一個(gè) object?[],所以無法直接取數(shù)據(jù);而使用 == 會(huì)引起數(shù)據(jù)比較的錯(cuò)誤:因?yàn)樽髠?cè)是 object 類型,右側(cè)是 int 類型,等號(hào)就會(huì)認(rèn)為是倆 object 的引用比較,所以是錯(cuò)誤的用法。

總結(jié)一下。只要類型:

  • 有一個(gè) this[int] 的索引器,且必須有 get 語句;

  • 有一個(gè)叫做 Length 或者是 Count 的屬性。

那么類型就可以使用長(zhǎng)度模式對(duì)具體某個(gè)元素作匹配。

Part 15-2 集合模式

長(zhǎng)度模式我們說完了,接下來說一下集合模式。當(dāng)長(zhǎng)度模式要連續(xù)拼接多個(gè)元素判斷的時(shí)候,長(zhǎng)度模式就顯得很麻煩了。那么,集合模式就出現(xiàn)了。

舉個(gè)例子。如果我們拿到了一個(gè)集合,但我們不知道集合的元素都有些什么,那么,我們最初的寫法可能就成這樣了:

顯然,這種寫法就很讓人頭疼。因?yàn)椴恢?obj 的類型就開始判斷對(duì)象的數(shù)據(jù)了,顯然是很麻煩的。C# 10 提供了一種輕快的語法:

我們來說一下,這個(gè)寫法是啥意思。首先,{ 1, 2, 3, .. } 是集合模式。它表示判別的序列,要滿足前三個(gè)元素和這里的順序一一匹配的 1、2、3。雙小數(shù)點(diǎn)記號(hào)(范圍記號(hào),下面的切片模式會(huì)用到這個(gè)符號(hào)) .. 在 C# 8 里就有,它表示取序列的一部分。在模式匹配里(就是這里),這個(gè)記號(hào)表達(dá)的是“后面還有別的數(shù)據(jù),不過我們不作驗(yàn)證了”。換句話說,{ 1, 2, 3 }{ 1, 2, 3, .. } 是兩個(gè)不同的意思:前者表示必須序列只有三個(gè)元素,且必須依次是 1、2、3;而后者則可表示元素至少有三個(gè),只要前三個(gè)順次是 1、2、3 就可以了;后面不管是啥都行。

啰嗦一下。由于 int[]{ 1, 2, 3, .. } 這兩個(gè)模式是分開的兩個(gè)匹配邏輯(一個(gè)是類型判斷,一個(gè)是數(shù)據(jù)判斷),且它們是且的關(guān)系,因此按道理來說,是可以加 and 在中間的:is int[] and { 1, 2, 3, .. }。實(shí)際上可以嗎?可以的。但是沒有必要,因?yàn)?C# 知道這里是兩個(gè)判斷的關(guān)系。所以這里的 int[] { 1, 2, 3, .. } 雖然看起來有點(diǎn)像數(shù)組的初始化器,但編譯器是知道這里不是在初始化數(shù)組,而是一個(gè)判斷的兩個(gè)條件(一個(gè)判斷類型的條件和一個(gè)判斷數(shù)據(jù)的條件)。

不過,啥樣的數(shù)據(jù)類型可以使用和校驗(yàn)?zāi)兀考热粚?duì)象可以解析數(shù)據(jù),那么前面要滿足長(zhǎng)度模式的要求必須都得滿足。因此:

  • 有一個(gè) this[int] 的索引器,且必須有 get 語句;

  • 有一個(gè)叫做 Length 或者是 Count 的屬性。

依然是這樣的條件。

Part 15-3 切片模式

那么,集合貌似有了判斷模式了,好像差不多可以結(jié)束了。C# 10 還提供了一種新鮮的語法,除了以數(shù)據(jù)為單位判斷,還可以以數(shù)據(jù)序列作為切片。

C# 8 里有這么一種語法:arr[0..10],這表示把 arr 的前 10 個(gè)元素取出來,而這個(gè)語法叫切片(Slice)。只要有一個(gè)方法 Slice(int, int) 定義切片的邏輯,那么對(duì)象就可以切片了。C# 10 里允許我們使用切片到模式匹配里。舉個(gè)例子,expr is { 1, .. var s, 3 } 就表示我們對(duì)中間的序列作切片,然后切片結(jié)果用 s 變量表示,因此,這個(gè)寫法等價(jià)于 expr.Length >= 2 && expr[0] == 1 && expr[^1] == 3 && expr[1..^1] is var s。特別要注意的是,這里第一個(gè)條件并不是直接數(shù)值判斷,而是長(zhǎng)度判斷:expr.Length >= 2。這是因?yàn)楹罄m(xù)的條件無法保證對(duì)象的長(zhǎng)度是多少,貿(mào)然取值會(huì)導(dǎo)致 IndexOutOfRangeException 的異常。

那么,給一些例子給你看看。

這里的下劃線是棄元(Discard)語法。我們不在意這里的數(shù)據(jù)是多少,但必須要占位來表示這里是集合的第幾個(gè)元素,就使用棄元來表達(dá)(后兩種情況就用到了占位這個(gè)概念)。

另請(qǐng)注意,這里 expr 是不知道啥類型的,所以可能集合內(nèi)的元素都是 object。因此在注釋里用的是 is 而不是 ==。

當(dāng)然了,如果只有一個(gè)切片的范圍記號(hào) ..,而不判斷數(shù)據(jù)的話(即 { .. }),就等價(jià)于 obj.Length >= 0 這個(gè)條件,或者 obj is { Length: >= 0 }。另外,后者這個(gè)寫法還比前者多判斷一下 nullobj is not null and { Length: >= 0 };而前者只判斷 Length 屬性是不是至少為 0。

Part 15-4 混用模式匹配

我們來總結(jié)一下 C# 7 開始允許的所有模式匹配:

  • C# 7

    • expr is T value(增強(qiáng) is 模式)

    • expr is var variablevar 模式)

    • expr is var (value1, value2, value3)(解構(gòu)模式)

    • expr is var (_, _, value3, _)(棄元模式)

  • C# 8

    • expr is { Property1: value1, Property2: { InnerProperty: value2 } }(遞歸模式)

    • expr is { } notNullResult(空遞歸模式/不可空校驗(yàn)?zāi)J剑?/span>

  • C# 9

    • expr is var value and not (value1 or value2)(邏輯模式)

  • C# 10

    • expr is { [index]: value }(長(zhǎng)度模式)

    • expr is { value1, value2, _, .., value3, .., value4, _ }(集合模式)

    • expr is { _, _, .. var slice, _, _ }(切片模式)

當(dāng)我們需要混用的時(shí)候,需要注意一下要求。由于很多的模式匹配上都是用大括號(hào)來表達(dá)和標(biāo)記模式匹配的范圍和界限,因此如果混用可能就導(dǎo)致語法不清晰。因此,C# 10 只能讓我們把集合和切片模式寫在整體的最后面;而前面則是 C# 7 到 9 里的基本模式匹配。

這樣的寫法。

C# 10 特性一覽的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
青冈县| 汤阴县| 浑源县| 吉安市| 湖口县| 花莲市| 交口县| 建始县| 桃江县| 竹北市| 建平县| 塔河县| 平陆县| 桂林市| 聂荣县| 横山县| 灌云县| 招远市| 泰宁县| 循化| 长子县| 蒙阴县| 兴文县| 砚山县| 湘潭县| 武汉市| 六盘水市| 定远县| 交口县| 庆云县| 堆龙德庆县| 洛宁县| 镇远县| 大冶市| 根河市| 永泰县| 微博| 旌德县| 读书| 凤翔县| 南开区|