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

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

探索 C# 12 的 ref readonly 參數(shù)修飾符

2023-09-14 21:35 作者:SunnieShine  | 我要投稿

在 Visual Studio 17.8 Preview 2 里我們可以使用該特性。該特性允許用戶(hù)使用 ref readonly 修飾符修飾參數(shù),表示該引用只讀。

Part 1 C# 似乎已經(jīng)有這種特性了

我們?cè)谛揎梾?shù)的時(shí)候,我們?nèi)绻獋鬟f一個(gè)引用而不是數(shù)值的話,我們可以采用 ref 修飾符來(lái)修飾它,這樣表示的是該參數(shù)傳入的是這個(gè)變量的地址數(shù)據(jù),而不是內(nèi)部的數(shù)值。

如代碼所示,我們展示的是一個(gè) ref 修飾符修飾過(guò)的參數(shù)的一個(gè)例子??梢钥吹?,它的記號(hào)寫(xiě)法和 C/C++ 里的地址和引用沒(méi)有多少區(qū)別。只是 C# 里把 C++ 的引用記號(hào)改造成 ref 關(guān)鍵字了而已:

以及

不過(guò),C# 如果要限制引用只讀的話,可能只能換個(gè)修飾符了。和 C/C++ 不同,C/C++ 具有 const 修飾符,而 C# 呢?別急。C# 有 in 關(guān)鍵字。

從 C# 7 開(kāi)始,C# 允許使用 in 修飾符替換 ref,表示變量傳入的是只讀引用。所謂只讀引用,指的是對(duì)象傳入的是它的地址,且該地址內(nèi)的數(shù)據(jù)不能變動(dòng)(你只能讀取里面的數(shù)值來(lái)用,而不能修改它內(nèi)部的數(shù)據(jù))。

是的。這個(gè)玩意兒在 C# 7 就有了。那么,下面我們要說(shuō)的 ref readonly 是個(gè)什么呢?

Part 2 限制指向的數(shù)值只讀

C# 12 所擁有的新特性 ref readonly 限制的是參數(shù)傳入的這個(gè)對(duì)象內(nèi)部的數(shù)值只讀。啊?這不是跟 in 參數(shù)修飾符的用途完全一樣嗎?這沒(méi)什么區(qū)別啊……

是的,沒(méi)有啥特別大的區(qū)別。要說(shuō)區(qū)別的話,還是有的。下面我們來(lái)說(shuō)下 C# 12 這個(gè) ref readonlyin 的區(qū)別。

2-1 參數(shù)值需要用 in 修飾

C# 12 的 ref readonly 修飾符和 in 幾乎一致,因此你寫(xiě)的幾乎所有帶有 in 修飾符的地方全都能替換為 ref readonly。

這幾乎不會(huì)造成區(qū)別。但是調(diào)用方就不一樣了。

原本的調(diào)用方,in 修飾符修飾的參數(shù),參數(shù)表達(dá)式(數(shù)值等)都不需要使用配套的 in 修飾。你直接用就行了:

這一點(diǎn)造成了和 refout 修飾的參數(shù)不一致的語(yǔ)法:ref 修飾的參數(shù),在調(diào)用的時(shí)候也需要寫(xiě)出來(lái) ref 關(guān)鍵字表達(dá)這里傳入的是引用。微軟這么規(guī)定是為了可讀性和一些編譯器在語(yǔ)法上的解析的便捷。當(dāng)然,out 修飾符也是一樣。調(diào)用方你也需要顯式給出 out 修飾符。但 in 修飾符是一個(gè)例外。你可以調(diào)用的時(shí)候不需要給這個(gè) in 也是 OK 的。當(dāng)然,寫(xiě)出來(lái)也行。

但是,C# 12 的這個(gè)新修飾符 ref readonly 必須要求你顯式寫(xiě)出 in 修飾符,表示這里傳入的是一個(gè)只讀引用。

如果不寫(xiě)會(huì)怎么樣呢?不會(huì)怎么樣,但是你會(huì)收到一個(gè)編譯器警告。告知你這里必須給出 in 修飾符。如果你忽略警告,也沒(méi)有任何問(wèn)題;你在運(yùn)行的時(shí)候程序仍然可以正確得到預(yù)期的結(jié)果。

這種使用編譯器警告代替?zhèn)鹘y(tǒng)的編譯器錯(cuò)誤的操作,實(shí)際上有兩層考慮:

  1. 因?yàn)樗?in 修飾符相似,所以考慮用戶(hù)兼容語(yǔ)法的習(xí)慣,不強(qiáng)制要求添加;

  2. 因?yàn)榫幾g器即使你不加修飾符 in 也可以正確分析代碼,因?yàn)樗肋@里傳的是只讀引用。

很好。我希望我解釋得足夠清晰了。下面我們來(lái)說(shuō)說(shuō)為什么用的是 in 修飾傳入的參數(shù)表達(dá)式。

按道理說(shuō),因?yàn)槭?ref readonly,所以按照契合 C# 臨時(shí)變量對(duì)只讀引用的定義用法,右值表達(dá)式(等號(hào)右側(cè)的表達(dá)式)是配合左邊定義變量用的 ref 關(guān)鍵字,所以使用的也是 ref 修飾符:

可以看到,這個(gè)的修飾符組合起來(lái)也是 ref readonly,但右邊用的是 ref;而為什么參數(shù)的 ref readonly 修飾符,傳入進(jìn)來(lái)的表達(dá)式卻要求用 in 而不是 ref 呢?

其實(shí)是因?yàn)?ref 在 C# 里固定的是一種傳入引用的意思。雖說(shuō) ref readonly 表達(dá)參數(shù)也是說(shuō)傳引用(雖然是引用的成員只讀),但它更多想要強(qiáng)調(diào)的是數(shù)值上的不可變。和臨時(shí)變量不同,臨時(shí)變量在定義的時(shí)候右值表達(dá)式是期望和等號(hào)左側(cè)聲明達(dá)到一個(gè)契合狀態(tài),所以使用同樣的修飾符可以更加直觀;而在這里用 in 修飾右值表達(dá)式則反而不太能搞清楚它表達(dá)的意思。

所以這實(shí)際上是一種對(duì)語(yǔ)法書(shū)寫(xiě)的習(xí)慣而造成的原因。

2-2 不能傳常量

這是最為致命的一個(gè)問(wèn)題。C# 7 誕生的 in 修飾符表示的是參數(shù)的只讀;不過(guò),這并未限制一些特有的看似 bug 的特殊情況——常量。

常量我們都知道,它必然是只讀的。而 in 修飾符的作用本就是表示內(nèi)部的數(shù)值只讀,這正好契合常量想要表達(dá)的內(nèi)在含義??蓡?wèn)題在于,正是因?yàn)槌A繚M(mǎn)足只讀的操作,因此傳入常量是一種特別奇怪的行為:

可以看到這樣的代碼將變得毫無(wú)意義可言。既然 42 是一個(gè)常量傳入,那我為什么不直接讓它用 int 而反倒去傳引用還讓對(duì)象只讀呢?

C# 主要是為了解決這種操作,所以才使用新概念 ref readonly 來(lái)代替原有的 in 修飾符。它的作用主要是限制常量的使用。顯然用戶(hù)很少會(huì)在常量上面使用只讀引用的傳遞,所以這種操作對(duì)用戶(hù)層面而言幾乎不會(huì)存在;但從另外一個(gè)角度來(lái)說(shuō),微軟定義 C# 的其中一個(gè)主要特征就是兼容性。早期版本帶來(lái)的陋習(xí)你可以不用,但微軟不會(huì)刪掉它;怕的是用戶(hù)在使用新版本語(yǔ)法的時(shí)候,舊版本不可用進(jìn)而導(dǎo)致的新版本編譯失敗的問(wèn)題。

這就是為什么微軟會(huì)強(qiáng)行搞出一個(gè)新的概念來(lái)避免改動(dòng) in 的語(yǔ)義。而有了 ref readonly 之后,42 因?yàn)槭浅A克晕覀儫o(wú)法取該對(duì)象的地址,因而無(wú)法對(duì)其使用引用,這便是 ref readonly 修飾符和 in 修飾符修飾的參數(shù)在使用上的唯一區(qū)別。

Part 3 其他地方的影響

該語(yǔ)法主要是改變和避免用戶(hù)誤用、錯(cuò)用修飾符來(lái)控制對(duì)象內(nèi)數(shù)據(jù)是否只讀的問(wèn)題。

3-1 函數(shù)指針

很明顯,函數(shù)指針受到了影響。我們?cè)谛揎椀臅r(shí)候可使用 ref readonly 放在參數(shù)的位置而不一定只在最后:

3-2 元數(shù)據(jù)

在元數(shù)據(jù)里,C# 使用 RequiresLocationAttribute 來(lái)限制 ref readonly 修飾符的行為。換言之,修飾符如果是 ref readonly 的話,那么該參數(shù)將會(huì)帶上 RequiresLocationAttribute 特性作為元數(shù)據(jù)底層。這樣的話可以區(qū)分已有 in 修飾符所使用的元數(shù)據(jù),避免兩者靠編譯器無(wú)法區(qū)分的問(wèn)題。

不過(guò)這一點(diǎn)對(duì)我們使用代碼影響其實(shí)并不大。


探索 C# 12 的 ref readonly 參數(shù)修飾符的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
安徽省| 德令哈市| 巫山县| 桃江县| 蒲城县| 虎林市| 大方县| 永登县| 临颍县| 江口县| 阳新县| 天津市| 周宁县| 宜宾市| 南郑县| 梨树县| 瑞安市| 象山县| 东阿县| 博爱县| 疏附县| 忻城县| 新闻| 尼玛县| 葫芦岛市| 宝清县| 丽江市| 永泰县| 彭州市| 上栗县| 自贡市| 太白县| 保亭| 梓潼县| 南平市| 阆中市| 南郑县| 镇沅| 汝州市| 绥棱县| 武邑县|