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

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

C# 解構(gòu)模式

2023-01-14 22:26 作者:SunnieShine  | 我要投稿

1、語(yǔ)法

因?yàn)榍拔奈覀儞碛辛私鈽?gòu)函數(shù),也擁有了 var 模式,因此 C# 靈活的語(yǔ)法提供了 var 模式的解構(gòu)版本:

稍微注意一下這里的語(yǔ)法是寫成 var (x, y)。當(dāng)然,你也可以內(nèi)聯(lián) var 關(guān)鍵字。和值元組的語(yǔ)法一致,你依然可以用 (var x, var y) 的語(yǔ)法。

這樣是可以的。

不過嚴(yán)謹(jǐn)一點(diǎn)的話,var (x, y) 是解構(gòu)模式,而 (var x, var y) 是對(duì)位模式。因?yàn)榍罢呤褂?var (x, y) 語(yǔ)法,小括號(hào)里直接定義了變量名,小括號(hào)的外側(cè)則是 var 關(guān)鍵字;但 (var x, var y) 在小括號(hào)里定義了兩個(gè)變量,都使用了 var 關(guān)鍵字,這意味著是對(duì)應(yīng)位置上的數(shù)據(jù)分別定義變量,類似 point.X is var x && point.Y is var y 的效果,因此只能說(shuō)是對(duì)位模式。

使用解構(gòu)模式可以更清楚、更簡(jiǎn)明地將對(duì)象進(jìn)行解構(gòu),直接賦值到變量上;但它存在一定的弊端,例如解構(gòu)模式下就不能往里判斷數(shù)值了。也就是說(shuō),你在寫成 var (a, b) 的類似語(yǔ)法后,就無(wú)法往 a、b 上使用任何模式匹配的判別語(yǔ)法了。該嵌套模式匹配之語(yǔ)法將在稍后說(shuō)明。

2、可空值類型解構(gòu)模式的別樣意義

在 C# 里,可空值類型一直是一種方便也不方便的數(shù)據(jù)類型。它的聲明和使用都比較方便,但問題就出在它可能是 null 數(shù)值。假設(shè)前文的 Point 我們用的是可空類型的話:

此時(shí),我們?cè)诤罄m(xù)的代碼里,無(wú)從根據(jù)代碼直接確定 nullable 是否為 null(除非看取了 nullable 的值才行)。因此,一旦我們對(duì)這個(gè)類型進(jìn)行解構(gòu):

這就不單純和 var 模式一樣。它牽扯到數(shù)據(jù)是不是 null 才可解構(gòu)的問題。如果數(shù)據(jù)都是 null 了,我們就無(wú)法解構(gòu)。因此,可空值類型的解構(gòu)模式會(huì)先判斷對(duì)象是不是不為 null,然后才是解構(gòu)。

nullable != nullnullable.HasValue 是等效的,所以寫 nullable.HasValue 也沒問題。

3、主構(gòu)造器的解構(gòu)模式

是的,主構(gòu)造器會(huì)自動(dòng)生成對(duì)應(yīng)的解構(gòu)函數(shù),因此完全可以直接使用解構(gòu)模式。還是使用之前的 Person 類型:

那么,有這樣的語(yǔ)法:

這樣是允許的。但你不能寫 is Person (name, _, isBoy),因?yàn)榍懊娴?var 關(guān)鍵字是這個(gè)模式匹配的固定格式,改成了 Person 的話,后面就只能看成對(duì)位模式了。

4、調(diào)用擴(kuò)展方法的解構(gòu)模式

解構(gòu)模式和對(duì)位模式類似,編譯器也支持嗅探解構(gòu)模式對(duì)應(yīng)的擴(kuò)展方法。一般正常的實(shí)現(xiàn)我們可能對(duì)一些數(shù)據(jù)類型無(wú)法實(shí)現(xiàn)解構(gòu)操作,因此我們需要擴(kuò)展方法來(lái)達(dá)到一些行為。比如假設(shè)我要去獲取數(shù)組的前兩個(gè)元素,我們經(jīng)常會(huì)使用 [0][1] 來(lái)獲取,不過現(xiàn)在我們可以使用解構(gòu)模式來(lái)完成:

假設(shè)我隨便這么寫了這個(gè)擴(kuò)展方法,它們用于解構(gòu) T[] 數(shù)組。于是我們可以對(duì)一個(gè)一維數(shù)組進(jìn)行解構(gòu)操作:

請(qǐng)注意解構(gòu)函數(shù)正常使用的時(shí)候是盡量不出現(xiàn) 0 或 1 個(gè)元素的解構(gòu)模式,不過在這個(gè)時(shí)候也可能會(huì)遇到,因此語(yǔ)法沒有對(duì)此進(jìn)行限制。

5、解構(gòu)和對(duì)位模式不要求判斷元素?cái)?shù)量至少兩個(gè)

這里稍微說(shuō)一個(gè)比較不容易了解到的知識(shí)點(diǎn)。編譯器限制我們定義一個(gè)至少兩個(gè)元素的值元組 ValueTuple 類型,也就是說(shuō),一個(gè)或零個(gè)的值元組類型是不被允許的:

注意,第 2 行的代碼我們假設(shè)寫的 var 而不是 ValueTuple<int> 的話,編譯器會(huì)自動(dòng)消去 (1) 兩側(cè)的小括號(hào),然后直接認(rèn)為它是 1;故意顯式給出類型名是為了告訴你,這兩個(gè)情況都是值元組不被允許的。

不過,雖然解構(gòu)模式和對(duì)位模式長(zhǎng)得都跟值元組的類型聲明模式很像,但對(duì)位模式和解構(gòu)模式允許和支持解構(gòu)函數(shù)可以包含任意多的 out 參數(shù)用于解構(gòu),這也意味著在解構(gòu)模式和對(duì)位模式里,is ()is (1) 是存在的語(yǔ)法。

6、單元素的解構(gòu)模式要手動(dòng)消除二義性

在 C# 里,小括號(hào)如果不需要是會(huì)被編譯器分析出來(lái)的。比如說(shuō) var a = (1 + 3),此時(shí)的小括號(hào)沒有必要需要它。在模式匹配里,單元素的解構(gòu)模式也是一種特殊的處理:它會(huì)被視為常量模式,于是,考慮下面的例子,判斷就有些奇怪了:

請(qǐng)看這樣的代碼。你認(rèn)為它是對(duì)的嗎?答案是不對(duì)。編譯器會(huì)首先認(rèn)為 (42) 是常量模式,而 o 變量是 C 類型而不是一個(gè)整數(shù),因此這個(gè)模式會(huì)導(dǎo)致編譯器直接告知“永遠(yuǎn)都不會(huì)匹配成功”的編譯器錯(cuò)誤。

那么,怎么讓它調(diào)用該解構(gòu)函數(shù)來(lái)完成判別呢?答案其實(shí)很簡(jiǎn)單:消除編譯器認(rèn)為是常量模式的二義性即可。比如給 (42) 模式添加參數(shù)名。

這樣編譯器就不會(huì)簡(jiǎn)單認(rèn)為是一個(gè)常量了。

7、任意類型的解構(gòu)模式

對(duì)任何數(shù)據(jù)類型(當(dāng)然,指針類型除外)而言,我們都是可以使用解構(gòu)模式的。這一點(diǎn)很神奇。

可,這會(huì)被視為什么判斷規(guī)則呢?不知道你知不知道一個(gè)類型叫 ITuple?這個(gè)數(shù)據(jù)類型限制了類型具有元組的性質(zhì)。所以,對(duì)任何數(shù)據(jù)類型來(lái)說(shuō)的解構(gòu)模式,實(shí)際上是被編譯器特殊處理和優(yōu)化過,并認(rèn)為是在匹配該類型的數(shù)據(jù)規(guī)則。

比如 o is () 會(huì)被視為 o is ITuple tuple && tuple.Length == 0。注意此時(shí) ITuple 里的 Length 屬性表示的是元組的元素?cái)?shù)。當(dāng)然了,如果你這個(gè)類型具有解構(gòu)函數(shù),就不會(huì)走這個(gè)路線去判斷。但是,如果一個(gè)類型既沒有實(shí)現(xiàn)這個(gè) ITuple 接口,又沒有匹配的解構(gòu)函數(shù),就會(huì)產(chǎn)生編譯器錯(cuò)誤。


C# 解構(gòu)模式的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
石城县| 玉林市| 彭水| 泗水县| 施甸县| 黄陵县| 绥阳县| 上犹县| 广河县| 红桥区| 同心县| 商河县| 汽车| 龙游县| 鹤岗市| 邯郸市| 祁连县| 郴州市| 湘潭市| 开封县| 闽侯县| 南投市| 乐陵市| 潍坊市| 平谷区| 桃源县| 长乐市| 兰考县| 木兰县| 酒泉市| 富裕县| 扎鲁特旗| 织金县| 大名县| 峨边| 秦皇岛市| 建瓯市| 湘潭市| 宁德市| 金川县| 洛浦县|