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

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

第 107 講:C# 3 之查詢表達(dá)式(十一):let 的底層原理

2022-05-04 08:43 作者:SunnieShine  | 我要投稿

今天我們來學(xué)習(xí) let 從句的底層。

實際上,它和 select 的代碼基本上是一樣的,因此內(nèi)容并沒有想象的那么復(fù)雜。

Part 1 定義變量不就是多映射一個對象嗎?

首先我們應(yīng)當(dāng)思考一下,允許我們臨時在查詢表達(dá)式的中間定義變量,如果是你應(yīng)該怎么去實現(xiàn)。顯然我們最容易想到的辦法就是拿 Select 映射的時候帶上它就行了,對吧?

假設(shè)我現(xiàn)在有這樣的代碼。我們使用了一次 let 從句,然后把平均數(shù)的結(jié)果求出之后,然后使用在 select 從句里當(dāng)作反饋對象。如果是你,你肯定會說,let 用來定義變量,那么這個變量一定可以在稍后的代碼里使用。那么既然如此,我們肯定會使用一次 Select 方法來完成這個定義。

實際上,果然如此嗎?答案是,是的。它等價于這樣的方法調(diào)用:

我們連續(xù)使用兩次 Select 擴(kuò)展方法。第一次,我們使用 Select 是為了將平均數(shù)值算出來。可問題是這個數(shù)值還會被留著我們稍后使用,因此我們同時需要傳入兩個數(shù)據(jù),一個是原本的 score 匿名類型對象,另外一個則是此時的平均數(shù)值。

這么映射是有必要的。因為我們?nèi)绻话凑?let 從句那樣得到平均值映射出去的話,那么稍后我們就無法繼續(xù)再使用 score 這個匿名類型的變量了,因為第一個 Select 擴(kuò)展方法此時已經(jīng)只映射出了平均數(shù),而不再包含了原始信息,因此我們需要保證原來的數(shù)據(jù)不丟失的同時再次補(bǔ)充新數(shù)值(這個平均數(shù)值),這就是 let 從句的 Select 語句寫法。

接著,我們再次使用一次 Select 擴(kuò)展方法。這次我們因為從上面?zhèn)飨聛淼慕Y(jié)果是一個新的匿名類型:包含 RealScore 屬性和一個 Average 屬性,因此我們此時可以利用這兩個內(nèi)部屬性來表示最終的映射關(guān)系。顯然,我們要的就是這兩個內(nèi)部屬性的數(shù)值整合起來作為反饋結(jié)果。

似乎是合理的。我們試著將鼠標(biāo)放在 letselect 兩個關(guān)鍵字上,就可以查看到調(diào)用方法。首先是 let 從句。它轉(zhuǎn)為了一個 Select 擴(kuò)展方法的調(diào)用:

接著是 select 從句,也轉(zhuǎn)換為了一次調(diào)用:

這就是 let 從句的原理了。老規(guī)矩,呈現(xiàn)一下關(guān)系對應(yīng)圖。

Part 2 let 從句導(dǎo)致的無法避免的副作用:無法識別冗余性

當(dāng)然了,這里第二個 Select 擴(kuò)展方法的映射好像似乎沒有啥用,畢竟你完全可以直接將前面一個 Select 擴(kuò)展方法得到的結(jié)果直接作為結(jié)果反饋出來,畢竟前面已經(jīng)得到了這樣的匿名類型對象,恰好就是我們現(xiàn)在所使用的。換言之,上面的查詢表達(dá)式本身應(yīng)該翻譯為這樣:

我這里稍微換一下行書寫 Lambda 表達(dá)式,因為太長了,都寫到后面去了。雖然這么寫估計你看著也不太習(xí)慣,但是將就看,起碼這樣比剛才排版要看著舒服點。

但由于第 3 行的 Select 擴(kuò)展方法調(diào)用沒有任何意義,因此可以直接不要:

不過,這是照著前面的查詢表達(dá)式得到的結(jié)果,因此會有如此的“副作用”,這也是不可避免的,畢竟也沒人知道我必須得這么用。這也是為什么我們永遠(yuǎn)建議你,在有必要優(yōu)化的地方盡量使用 select-into 而不是 let 從句的真正原因:因為 let 從句會在編譯器翻譯為方法調(diào)用的時候,多傳入一個對象進(jìn)去,這樣有可能在之后的調(diào)用和處理過程期間導(dǎo)致一定的副作用,比如由于無法識別冗余映射關(guān)系而導(dǎo)致的多一次的方法調(diào)用過程之類的。

Part 3 題外話:說一下 Visual Studio 對匿名類型的顯示

3-1 “臨時類型記號”

不知道你剛才注意到?jīng)]有,Visual Studio 一直是把匿名類型顯示成帶撇號和小寫字母的寫法的。這種記號叫“臨時類型記號”(好吧這個名字是我取的),表示臨時變量定義過程之中,無法表示或表示起來超長的替代記號。

這樣的記號,目前只用在匿名類型的顯示上,因此可能你以為它是跟匿名類型綁定起來的概念,實際上并不是。在以后我們學(xué)了值元組(C# 7 起可用)以及 Lambda 和方法組加強(qiáng)(C# 10 起可用)之后,這樣的記號會被廣泛用到,而且因為委托類型、結(jié)構(gòu)和匿名類型三者都是不同的表示數(shù)據(jù)類型的類別(目前可用的有結(jié)構(gòu)、類、枚舉、接口以及委托這五種類別的數(shù)據(jù)類型),因此在 Visual Studio 上,甚至表現(xiàn)出來的顏色可能都會不一樣。所謂的顏色就是呈現(xiàn)給你看的這個“小貼士”上,剛才所說的這種所謂“臨時類型記號”的文字的顏色,說的是這個顏色不一樣。比如匿名類型顯示成青綠色:

C# 7 的值元組語法顯示成紫色(我這個電腦把它設(shè)置成的紫色,可能在你電腦上它是別的顏色,比如黃綠色):

而 C# 10 的匿名委托類型語法則顯示為深一點的青色:

當(dāng)然,新的特性還需要等著我們?nèi)ヂ剿?,現(xiàn)在才到 C# 3 呢。

3-2 奇奇怪怪的問題:如果記號里的字母用完了呢?

顯然我們這里顯示這些匿名類型的時候,都是用的所謂的 'a、'b、'c 之類的記號在顯示,那么字母用完了呢?

這你不用擔(dān)心,如果 26 個小寫字母用完了,它不會再替換為大寫字母,因為這樣容易分不清楚,而是替換為顯示成數(shù)字,比如 '27、'28 等等。

極端一些,咱們來試一下。

誠不我欺。這里咱們隨便寫了一堆嵌套的匿名類型,每一個匿名類型都嵌套一個屬性,屬性的數(shù)值則是上一層的匿名類型。反正就硬套唄,為了顯示效果而已??梢钥吹阶詈笕齻€匿名類型已經(jīng)用完了字母,因此顯示為數(shù)字,從 26 開始編號,因為匿名類型第一個 'a 編號是從 0 開始的(雖然這一點并未呈現(xiàn)在圖里面)。

第 107 講:C# 3 之查詢表達(dá)式(十一):let 的底層原理的評論 (共 條)

分享到微博請遵守國家法律
桐城市| 和田市| 吴江市| 东丽区| 望谟县| 卓尼县| 万荣县| 河东区| 霍邱县| 临澧县| 合江县| 正镶白旗| 上杭县| 阜阳市| 垦利县| 明溪县| 卢湾区| 敦化市| 巴林左旗| 无极县| 洛隆县| 屯留县| 嘉黎县| 竹山县| 宁晋县| 鹤壁市| 库尔勒市| 永丰县| 吉安市| 安陆市| 藁城市| 高淳县| 龙州县| 宜君县| 开原市| 芦溪县| 依兰县| 浮梁县| 堆龙德庆县| 南澳县| 石城县|