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

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

第 117 講:C# 4 之命名和可選參數(shù)

2022-06-14 21:24 作者:SunnieShine  | 我要投稿

今天我們要說的是命名參數(shù)和可選參數(shù)。這個特性是為了更加輕便、靈活使用參數(shù)而制定的語法。先來說可選參數(shù)。

Part 1 可選參數(shù)

可選參數(shù)(Optional Parameter)是一種將兩個重載版本代碼基本一致的時候,抽取成一個方法的操作。

1-1 基本語法

比如說,我現(xiàn)在要使用冒泡排序法來排序,不過我們?yōu)榱俗層脩艨梢造`活使用,我們再提供一個重載版本,讓用戶自定義排序的委托。

可以發(fā)現(xiàn),兩個代碼唯一的區(qū)別是參數(shù)不同,以及 if 判斷不同。顯然,既然大部分代碼相同,就小部分不一樣的話,我們這么重載雖然可以運行,但不便于維護。于是,C# 4 允許我們往參數(shù)上賦初始常量數(shù)值。

我們注意到第 7 到第 9 行代碼,我們使用了一個三目運算符來判斷這個參數(shù)。如果這個參數(shù)是 null,就說明它是初始值,于是就使用 int 的默認比較規(guī)則來進行比較;否則,如果定義了的話,就使用 comparison 參數(shù)來進行比較。

注意,由于只有常量是安全使用,所以只能往參數(shù)上賦常量數(shù)值。如果你要賦變量或者是別的成員引用的話,是不允許的,畢竟你沒辦法確定這樣做是否會變更對象的信息,導(dǎo)致不安全的事情發(fā)生。

我們把 comparison 參數(shù)稱為可選參數(shù)。它上面有一個默認數(shù)值。那么這個方法怎么使用和調(diào)用呢?

由于該參數(shù)具有默認數(shù)值,因此如果你不使用參數(shù)的話,可以完全不考慮此參數(shù),直接當成“少一個參數(shù)”的方法來進行調(diào)用。比如說,這個參數(shù)有兩個參數(shù),第一個參數(shù)必須傳入,那么我們傳入 arr 變量;而第二個參數(shù)保持 null 就不管它:

就可以了。它和寫成 Sort(arr, null); 是一樣的。

1-2 注意事項

除了前面說的只能賦常量作為默認數(shù)值這個限制以外,還具有一些注意事項。

第一個,它并不會影響你代碼的執(zhí)行和簽名規(guī)則。它只是給參數(shù)帶了一個初始數(shù)值,但是參數(shù)的個數(shù),參數(shù)的類型等等信息,都是不受影響的,所以比如重載兩個方法,如果僅僅區(qū)別在于可選參數(shù)上的話(比如有一個重載有賦默認參數(shù)數(shù)值,有一個沒有),這樣并不會構(gòu)成重載。

第二個,它的有無不僅僅是可以用于實際方法上,也可以用于抽象的成員上。這里的抽象除了指抽象類型(包含 abstract 修飾符的方法),還可以用戶接口的方法成員。舉個例子:

如代碼所示,C 類型同時實現(xiàn)了兩個接口 IJ,且這兩個接口里的方法 F 唯一區(qū)別只有參數(shù)是可選和不可選而已。但是,在 C 類型的實現(xiàn)上,是不需要你關(guān)心是否也需要帶默認參數(shù)數(shù)值的。在第一點里我沒說過,它不影響程序的編譯和重載規(guī)則,因此 IJ 即使有可選參數(shù)的區(qū)別,但它們倆不構(gòu)成邏輯上的重載。換句話說,哪怕這倆方法寫在同一個接口里,編譯器是會報錯的,畢竟會被認為是同一個方法:同一個方法不能重復(fù)聲明。

但是,在實現(xiàn)上,C 類型不必關(guān)心該參數(shù)是否是可選的。這是為什么呢?因為該參數(shù)是否可選取決于你自己的實現(xiàn),所以你需要就設(shè)定,不需要就不設(shè)定,至少編譯器和運行時都知道你下一步的調(diào)用行為。我們使用多態(tài)規(guī)則來試試吧:

我們實例化了兩個 C 類型的對象,然后分別賦值給 IJ 接口的實例。因為 C 類型實現(xiàn)了這倆接口,所以這種轉(zhuǎn)換是成功的。接著,我們對 ij 變量都調(diào)用各自里面包含的 F 方法。由于 I 接口里包含的 F 方法具有可選參數(shù),因此你可以對此使用這樣的特性,不給該參數(shù)賦值,這樣的話,參數(shù)默認數(shù)值就是 42;而 J 接口的方法參數(shù)不是可選參數(shù),因此必須傳入數(shù)值進去。

這樣程序也不會有問題,而且也是預(yù)期的。

第三個,不僅參數(shù)的默認數(shù)值只能設(shè)置為常量,而且還不能有隱式轉(zhuǎn)換。舉個例子。

這種奇怪的賦值是合理的嗎?答案是否定的。這種賦值是錯誤的。雖然我們知道,字符串可以往 IEnumerable<char> 賦值,畢竟 string 實現(xiàn)了這個接口類型,但在可選參數(shù)上,這樣的賦值是不被允許的,原因在于它具有一次隱式轉(zhuǎn)換。而隱式轉(zhuǎn)換是運行時行為,換句話說,這種操作是不可在編譯時期而推斷的行為,畢竟你不知道后果如何。當然了,這里的轉(zhuǎn)換我們可以猜想到可能是沒有毛病的,但是對于一些我們自定義的類型來說,假設(shè)它們實現(xiàn)了這樣的接口,然后你去將字符串賦值過去。假設(shè)這個語法允許,那么它就會強制在編譯時期得到一次隱式轉(zhuǎn)換的規(guī)則,但你可以在這個隱式轉(zhuǎn)換的過程植入很多不是預(yù)期的代碼,然后逃避編譯器的檢查,這樣是很危險的。所以,這種賦值過程不被允許。

第四個,可選參數(shù)只能放在參數(shù)表列的末尾。舉個例子,比如你這么寫代碼是不可以的:

假設(shè)這樣的語法成立,我們調(diào)用該方法的時候,如果不對可選參數(shù)賦值,那么方法就成了這樣:

因為第一個參數(shù)我們不需要傳入數(shù)值,而你又必須標記一個逗號來分隔參數(shù),暗示 42 是第二個參數(shù)的位置上的數(shù)值。這樣肯定是不合語法邏輯和規(guī)則的。因此,C# 不允許這樣的語法。不過,類似這種缺省的調(diào)用語法,在別的編程語言可能是有的,比如 Visual Basic 里是支持這種寫法的。

第五個,可選參數(shù)不一定只能有一個??蛇x參數(shù)只要放在參數(shù)表列的末尾,你想有多少個都行,你甚至全都是可選參數(shù)也行。

Part 2 命名參數(shù)

命名參數(shù)(Named Parameter)的語法是,允許用戶將參數(shù)名寫在調(diào)用方。

2-1 基本語法

舉個例子,還是使用冒泡排序:

比如在第 4 行,我們傳入一個 arr 的時候,還允許我們手動寫 array: 來表示這個參數(shù)。嗯,說完了。

2-2 這有什么用?

可能有很多小伙伴覺得,這能有什么用?我為啥要花時間去多寫一下參數(shù)名稱?它的存在是有兩點意義:

  1. 標注一些常量參數(shù)傳入的時候的參數(shù)名,這樣使得代碼更具可讀性;

  2. 約束參數(shù)調(diào)用,使得我們的可選參數(shù)和必需參數(shù)(Required Parameter)使用起來更靈活。

我們來說說這兩點。

第一。假如我們傳入的參數(shù)是一個常量或字面量數(shù)值,這個時候如果沒有標注的話,就會顯得很難去看,特別是參數(shù)特別多的時候:

假設(shè)我有一個帶 6 個參數(shù)的方法。調(diào)用的時候假設(shè)長這樣:

對是對,但是我咋知道這些參數(shù)是啥。難不成我挨個都要去把鼠標放上去看?這不是遭罪么。那么我們有了命名參數(shù)之后,參數(shù)名寫出來就顯得很方便了:

雖然代碼更長了,但是起碼做到了參數(shù)名確定起來,代碼可讀性提高的作用。它也不影響你程序運行,寫不寫都對,但寫了更好看,所以命名參數(shù)有這個用。

第二。我們再來看這個方法。假如我們對最后兩個參數(shù)搞成可選參數(shù):

假如我指向給 maximumValue 參數(shù)賦一個另外的數(shù)值,但 minimumValue 我還是想用這個 0,這能做到嗎?

能。有了命名參數(shù)就能。我們只需要給前四個參數(shù)賦值之后,帶上參數(shù)名即可:

這樣寫之后,編譯器就知道,前面四個參數(shù)數(shù)值對位賦值到前面四個方法的參數(shù)里去,而最后一個參數(shù)由于給了參數(shù)名,因此會被識別為最后一個參數(shù) maximumValue,于是賦值給這個參數(shù)上。如果你不寫的話,這個時候按照賦值的匹配規(guī)則,順次賦值到方法參數(shù)之中去,就會讓 minimumValue 參數(shù)賦上 60 的數(shù)值,這就不是我們想要的結(jié)果了。因此,命名參數(shù)還有一個強約束可選參數(shù)的賦值的功能。

這就是這兩種參數(shù)的用法。我們就說完了。C# 4 也就全部結(jié)束了。

接下來是 C# 5。C# 5 的特性也不多(數(shù)下來一共也就三個特性),但是會有開幕雷擊的效果,因為第一個特性“異步方法”是特別難的點。在這個特性里我們會接觸到多線程的新架構(gòu)和模型,這也是我在早期講解多線程的時候挖的坑。在這里我們就會填坑完善這個多線程的使用體系和規(guī)則;另外,它還帶有一個全新的語法:asyncawait 關(guān)鍵字。如果用不好的話,會讓人完全不知道這個語法設(shè)計起來到底應(yīng)該怎么用。所以這個特性特別有得說。

而我打算停更一段時間,因為確實有點累,每四天更新一次這個語法教程的話,前面的語法還好,特別是這個 C# 5 的這個語法,有點復(fù)雜,四天說不定都不一定趕得上,而且感覺腱鞘炎有些嚴重了,所以我想暫時先休息一陣子。


第 117 講:C# 4 之命名和可選參數(shù)的評論 (共 條)

分享到微博請遵守國家法律
五原县| 黄骅市| 云霄县| 平陆县| 三江| 东兴市| 汉阴县| 桑日县| 阳江市| 会昌县| 临城县| 廉江市| 灯塔市| 天柱县| 长乐市| 南投县| 阳西县| 岑巩县| 连州市| 和顺县| 方山县| 汶上县| 靖远县| 寿宁县| 台南市| 扬州市| 旺苍县| 房山区| 全椒县| 师宗县| 任丘市| 且末县| 鄂托克旗| 沽源县| 南昌县| 德格县| 东乡族自治县| 右玉县| 宿迁市| 沈阳市| 萝北县|