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

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

第 88 講:C# 3 之隱式變量類型聲明

2022-02-17 11:02 作者:SunnieShine  | 我要投稿

歡迎來到 C# 3!今天我們來看第一個(gè)新語(yǔ)法:隱式變量聲明(Implicit-typed Variables)。

Part 1 var 關(guān)鍵字

考慮一種情況。如果我現(xiàn)在有一個(gè)巨長(zhǎng)無比的數(shù)據(jù)類型 Dictionary<int, Pair<string, IReadOnlyDictionary<string, decimal>>>。我們按照基本拆分的規(guī)則來看,這個(gè)可以表達(dá)一個(gè)學(xué)生的基本信息。Dictionary<int, ..> 類型的 int 作為鍵,搜索和唯一確定學(xué)生的學(xué)號(hào);而值則是 Pair<string, IReadOnlyDictionary<string, decimal>> 類型。Pair<,> 類型是隨便寫的,它用來表示一個(gè)數(shù)據(jù)對(duì),因?yàn)閱蝹€(gè)數(shù)據(jù)沒辦法存到這個(gè)字典里面,所以只能用一個(gè)單獨(dú)的數(shù)據(jù)類型表達(dá);接著,Pair 里帶有兩個(gè)泛型參數(shù),第一個(gè)實(shí)際類型為 string 想表示學(xué)生的名字,而右邊的 IReadOnlyDictionary<string, decimal> 則是一個(gè)字典,表示和存儲(chǔ)這個(gè)學(xué)生的各個(gè)科目的學(xué)習(xí)成績(jī)。string 是表示鍵,搜索和表示科目名,而 decimal 則對(duì)應(yīng)值,表示當(dāng)前科目的成績(jī)分?jǐn)?shù)。

可以看到,如果你這么實(shí)例化的話:

光一個(gè)實(shí)例化就得寫得巨長(zhǎng)。于是,我們可以借助 C# 2 的語(yǔ)法“類型別名”來完成:

或者:

不過,這么做也不合理的地方在于,這種類型沒必要單獨(dú)寫一個(gè) using。要遇到一堆這樣的東西,全部寫在 using 指令上去,一來是很不方便,二來是太長(zhǎng)了。放在 using 指令上還需要你手寫和寫全整個(gè)數(shù)據(jù)類型的所有位置上的類型的全名。

C# 3 引入了一個(gè)新的概念:隱式變量類型。我們?cè)谥皩W(xué)到的所有語(yǔ)法里,變量左側(cè)必須配上一個(gè)名字。這個(gè)名字一定是類型的名稱,不管是帶命名空間的,還是直接只寫名字,這種寫法我們都稱為顯式變量類型(Explicit-typed Variable)。有些時(shí)候名字比較長(zhǎng),或者是帶泛型的時(shí),泛型參數(shù)巨長(zhǎng)的時(shí)候,這么寫起來都不方便。

C# 3 使用關(guān)鍵字 var 來表示數(shù)據(jù)類型,于是你只需要在 new 后面寫一次變量的實(shí)際類型的實(shí)例化過程,就可以了:

在變量左側(cè)使用 var 代替掉原本完全寫出的顯式數(shù)據(jù)類型,這個(gè) var 就顯得非常方便了。

Part 2 用法

我們?cè)囍鴣肀硎竞褪褂?var 吧!

2-1 舉例

這個(gè)是排序的代碼。我們這次請(qǐng)看第 3、5 和第 9 行,我們都用到了 var 關(guān)鍵字??梢园l(fā)現(xiàn),var 的用法其實(shí)就是代替變量的數(shù)據(jù)類型,一勞永逸地使用 var 即可。

2-2 會(huì)不會(huì)降低了可讀性?

不過有人可能會(huì)問我,這樣不就降低了可讀性?我使用 var 看似是好事情,但此時(shí)變量 i、jtemp 變量的實(shí)際類型就不夠清楚了。這樣說不定會(huì)降低可讀性。不過我要告訴你的是,可讀性其實(shí)基本上沒有任何的降低,只是你不習(xí)慣。為什么我這么說呢?你仔細(xì)看看這些變量,它的實(shí)際類型其實(shí)我們并不關(guān)心。拿 ij 來看,難道你還在意它的數(shù)據(jù)類型具體是什么么?它是循環(huán)變量,我只需要知道它能 ++ 操作,它能當(dāng)成索引放在數(shù)組的中括號(hào)里去獲取元素不就行了?而下面的 temp 也是如此。我在操作里僅用到了交換,實(shí)際上它是啥類型我們并不關(guān)心。它是 T,而具體被啥類型替代,這些我們完全都不關(guān)心。

可能你會(huì)覺得,T 只打一個(gè)字符,而 var 卻要打三個(gè)字符出來,這不是反而復(fù)雜了?可我想說,第一,泛型參數(shù)用 var 完全是出于你熟悉了 var 語(yǔ)法后的習(xí)慣問題。你看到 var 既然廣泛被用上了,到處臨時(shí)變量都用 var 關(guān)鍵字代替了之后,突然在代碼里用了一個(gè)顯式數(shù)據(jù)類型,反而會(huì)覺得不統(tǒng)一,強(qiáng)迫癥患者表示也非常不舒服。第二是,真的時(shí)候,代替 T 這種少于三個(gè)字符的單詞的情況也不多。所有我們需要替代的數(shù)據(jù)類型,要么是關(guān)鍵字表示的(什么 sbyte 啊什么的),要么就是自己定義的數(shù)據(jù)類型。我們定義的數(shù)據(jù)類型很難取名只取只需要一個(gè)字符和兩個(gè)字符就可以的類型名稱。使用 var 再怎么說都比它們打起來方便。

真要抬杠的話,var 在少數(shù)情況也確實(shí)不及顯式數(shù)據(jù)類型,但沒有必要爭(zhēng)論這些細(xì)節(jié)上的問題,因?yàn)槲覀冃枰氖窃跁鴮懘a的時(shí)候要做到執(zhí)行效率和可讀性里找到折衷的方案,那么 var 確實(shí)達(dá)到了我們需求和想要的目的——替代復(fù)雜類型名稱。

Part 3 不能使用 var 聲明變量類型的情況

下面我們介紹一些關(guān)于 var 不能用的情況。

3-1 不能將 var 用于成員類型聲明、參數(shù)和返回值上

是的??紤]一種情況,假設(shè)我在類型聲明里用到了字段,是 var 類型的話:

這樣合理嗎?其實(shí)并不合理。我們要的目的是替代復(fù)雜類型名稱,但如果我們這里代替了的話,就會(huì)出現(xiàn)剛才說過的降低代碼可讀性的問題。這個(gè)字段是我們確確實(shí)實(shí)隨時(shí)隨地都可以用到的東西,而只有臨時(shí)變量只有小范圍才用得到,所以,超過臨時(shí)變量的使用范圍的話,代碼可讀性就會(huì)出現(xiàn)實(shí)打?qū)嵉亟档?。所以,C# 3 不允許我們將 var 用在可能會(huì)重復(fù)使用的地方上。

當(dāng)然,返回值和參數(shù)也都是如此。返回值不多說,但參數(shù)呢?因?yàn)閰?shù)是必須規(guī)定起來才能使用的,它也相當(dāng)于變量。但是問題就在于,參數(shù)的數(shù)值是從外部傳入的,而在方法里我們是無從知曉它的數(shù)據(jù)類型的,因此在定義和聲明方法的時(shí)候,參數(shù)的具體類型必須我們提前給出來。那么用 var 呢?你就不清楚是啥類型了,自然而然就是一種錯(cuò)誤使用了。

所以,總的來說,var 只用來表示一個(gè)臨時(shí)變量的類型,作為一種代替方案。

3-2 const 關(guān)鍵字不能和 var 一起用

C# 早期定義了 const 關(guān)鍵字,可以用在字段上表示字段是編譯前就得到的常量數(shù)據(jù)。而 const 實(shí)際上也可以修飾臨時(shí)變量,表示臨時(shí)使用的常量信息和數(shù)據(jù):

不過,C# 并不允許你在 const 修飾符后跟的類型名稱用上 var,即:

你可能會(huì)問,為什么???因?yàn)榭勺x性唄。一旦 const var 放在一起了,由于它是編譯前常量,因此它的作用會(huì)比正常的變量來說要大一些(不然,你為啥要修飾 const 呢?)。所以,這種情況下是有可能降低可讀性。

3-3 多變量同語(yǔ)句聲明的時(shí)候不能用 var

多變量的同語(yǔ)句聲明的語(yǔ)句是使用逗號(hào)分隔的方式:

在這種情況下,類型名稱不能用 var 替代。因?yàn)槭褂?var 對(duì)多變量賦值會(huì)使得語(yǔ)句的賦值變得奇奇怪怪的。

我們雖然可以按照從邏輯上的數(shù)據(jù)類型兼容的原則發(fā)現(xiàn),多變量定義放在同一個(gè)語(yǔ)句里的時(shí)候,必須要確保這些變量的數(shù)據(jù)類型全部要一樣,才能寫成“變量類型 變量1 = 數(shù)值, 變量2 = 數(shù)值, ...”的格式。可問題就出在,現(xiàn)在按字面量來看,1 是 int 類型的,而 1.2 則是 double 類型的。那么,這個(gè) var 是表示啥類型呢?這就不一定了。這 ab 定義語(yǔ)句顯然不允許同行,類型上就不匹配。

因此,C# 不允許同行多變量定義在同一個(gè)語(yǔ)句里面的時(shí)候,是不能用 var 的,否則會(huì)混淆編譯器的處理過程。

3-4 委托類型不能使用 var

這是一個(gè)奇怪的現(xiàn)象,也是可以說得通的現(xiàn)象。

考慮這個(gè)代碼。f 應(yīng)該表示什么?Console.WriteLine 是靜態(tài)方法組,表示執(zhí)行 Console.WriteLine 這個(gè)方法。但問題就在于,這個(gè)方法是有重載的,也就意味著參數(shù)類型我們無法從方法組里知道。因此,委托類型不允許使用 var 來賦值。

你必須改成這樣:

這樣,編譯器才知道,你這里調(diào)用的是 Console.WriteLine 方法里,傳入一個(gè) int 類型當(dāng)參數(shù)的那個(gè)重載版本。

3-5 聲明 var 的時(shí)候必須初始化

想想看,下面這個(gè)代碼是啥意思。

可以看到,i 在稍后被賦值了 20??蓡栴}就出現(xiàn)在編譯。因?yàn)榇a執(zhí)行和編譯看的是逐行的內(nèi)容,而 i 肯定不能因?yàn)槲液竺娴馁x值而反推前面代碼給出的 i 的數(shù)據(jù)類型,至少 C# 語(yǔ)法的嚴(yán)謹(jǐn)性不允許我們這樣做。因此,var 在使用的時(shí)候必須確保變量有賦值部分。如果變量沒有賦值部分,只是一個(gè)純變量定義的話,那么 var 是不能用在這種情況上的。

Part 4 是否選用 var 的抉擇

那么,啥時(shí)候用 var 合適呢?可以從前面的文字里看出,var 只要用在臨時(shí)變量上的話,隨便你啥時(shí)候定義類型,都可以用 var。但,可以用不代表必須這么用。所以選取 var 作為類型聲明還是需要我們抉擇一下的。

我這里做一個(gè)建議。我在寫代碼的時(shí)候,我會(huì)遵循這個(gè)規(guī)則去書寫代碼:

  • 如果是內(nèi)置類型具有關(guān)鍵字別名的,那么就寫關(guān)鍵字寫法,比如 int、float、string 等等;

  • 如果是枚舉類型,當(dāng)且僅當(dāng)它必須配合 const 修飾符的時(shí)候?qū)懭?,其它的時(shí)候都寫 var;

  • 其它任何臨時(shí)變量定義寫類型的時(shí)候,全部寫 var。

這是我認(rèn)為最合適的書寫習(xí)慣。

對(duì)沒錯(cuò),枚舉類型是可以用 const 修飾的。因?yàn)?const 修飾的是有編譯前常量的數(shù)據(jù)類型,而枚舉類型具有特征數(shù)值類型一個(gè)概念,因此枚舉類型基本上可以認(rèn)為是整數(shù)類型的命名數(shù)據(jù)類型,即相當(dāng)于給整數(shù)的數(shù)值都取了一個(gè)名字。那么本質(zhì)也是整數(shù),所以整數(shù)是有常量一說,自然枚舉類型也有常量一說了。

下面我們還是拿排序的例子來展示我使用 var 的情況。

那么,為什么有關(guān)鍵字的就寫關(guān)鍵字而不是寫 var 呢?考慮下面的代碼:

三個(gè)變量都可以用字面量 0 進(jìn)行初始化。因?yàn)橛须[式轉(zhuǎn)換。但是,如果我寫 var 的話:

這個(gè) var 只可能是 int。因?yàn)?var 只代替掉的是匹配的賦值方的表達(dá)式的整體類型。0 是 int 字面量,所以它最合適的類型是 int。

第 88 講:C# 3 之隱式變量類型聲明的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
武宁县| 郑州市| 哈巴河县| 全州县| 曲麻莱县| 乌拉特前旗| 湟中县| 庄河市| 长汀县| 太保市| 穆棱市| 介休市| 承德县| 上林县| 荆门市| 孝昌县| 酒泉市| 政和县| 麦盖提县| 岗巴县| 大化| 简阳市| 台中市| 普定县| 都安| 云安县| 鸡西市| 达日县| 丹巴县| 文成县| 宁陵县| 平江县| 信宜市| 托克托县| 通城县| 平远县| 资溪县| 婺源县| 齐河县| 揭东县| 平武县|