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

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

探索 C# 10 的 static abstract 接口成員

2021-08-30 17:36 作者:SunnieShine  | 我要投稿

C# 10 開始逐漸完善和支持接口里使用抽象的靜態(tài)成員,這樣就可以讓我們使用更靈活的代碼來完成更為廣泛的操作。

引例

考慮一種情況。我們總是喜歡對帶有加減乘除運算符的對象完成一些基本的操作和行為,但 int、double 甚至 nint 這樣的數(shù)據(jù)類型在 C# 里都帶有 + 運算符,如果我們嘗試著泛化執(zhí)行邏輯,以前的 C# 還不能完成這樣的任務。C# 10 開始,我們可以使用接口來完成。

首先我們讓所有這樣的數(shù)據(jù)類型支持 INumber<T> 接口:

然后,我們直接對這樣的接口來完成操作:

在這樣的代碼里,我們用到了 Default 屬性和 + 運算符。C# 以前的接口都無法對這樣的成員完成書寫和實現(xiàn),現(xiàn)在有了這樣的語法后,我們就可以完美支持這一點了。

特別注意語法 T.Default。我們使用泛型參數(shù)名后直接跟上 Default 的方式來表達我要獲取的是 T 這個數(shù)據(jù)類型下的 Default 屬性成員。為什么可以這么寫呢?因為 T 參數(shù)實現(xiàn)了 INumber<T> 接口,而這個接口里自帶 Default 成員。因此,我寫 T.Default 就意味著我直接取這個屬性的值。

語法

我們只需要在接口里的、你需要的必須讓類型實現(xiàn)的成員前面使用 static abstract 修飾符即可。注意,abstract 此時是不可缺少的。雖然我們知道 C# 里的接口默認以 public abstract 作為抽象的基本修飾符,但在這個特性里,我們不得不追加 static abstract 這個修飾符組合來同時表達它是靜態(tài)成員,且必須在實現(xiàn)類型里完成對這個成員的實現(xiàn)。

稍微注意一點。我們?yōu)榱俗尫盒蛥?shù)類型可以使用運算符操作,我們需要追加一個看起來好像沒用、但實際上很有用的泛型約束模式:where T : INumber<T>。是的,INumber<T> 接口是它自己,而這個泛型約束表示當前泛型參數(shù)類型 T 必須也實現(xiàn)它自己這個類型。這不是廢話嗎,難不成還可以不實現(xiàn)?

是的,它完全可以不實現(xiàn),甚至是毫不相關的情況。不妨思考一下,我們在使用 IEnumerable<T> 接口的時候,我們自定義的集合數(shù)據(jù)類型(比如假定叫 Class 類型),你在聲明的時候肯定不是這么寫的吧:

因為 Class 可能會封裝上一個比較小的集合類型的數(shù)據(jù)作為底層的數(shù)據(jù)類型實現(xiàn),比如我里面有一個 int[],那么 GetEnumerator 我恰好就直接把這個 int[] 類型的底層字段拿來取迭代器。這個時候,我們實現(xiàn)接口就應該是 IEnumerable<int>。可以看到,Class 類型的這個 Class 此時是和 IEnumerable<int> 里的這個 int 是完全不一樣的兩個數(shù)據(jù)類型。

而我們在為了使用泛型參數(shù)類型的運算符抽象的時候,我們寫上 where T : INumber<T> 的目的純粹就是為了表達“我自己這個類型就是實現(xiàn)這個接口的泛型參數(shù)”。如果沒有這層約束的話,那么我的泛型參數(shù) T 就可能和接口本身完全沒有關系。想一想我們 C# 最開始運算符重載的實現(xiàn)規(guī)則是不是有一條這樣的話:我們自定義的運算符重載,傳入的運算符參數(shù)必須至少有一個和這個類型本身一致,或為它的可空類型(即 T?,如果這里的 T 是值類型的話)。

是的,如果我們不使用泛型參數(shù)的“自實現(xiàn)”約束的話,這個參數(shù)就可能和接口無關,因此不符合 C# 基本實現(xiàn)的規(guī)則,達不到約束的目的。因此 C# 10 規(guī)定,你必須得讓泛型參數(shù)帶上“自實現(xiàn)”的約束,才可以使用對泛型參數(shù)的運算符重載的抽象化行為。

有了這層約束后,接口就顯得非常容易看了。我們再次把剛才的 INumber<T> 接口照搬過來:

這一次你再看看,是不是就沒問題了?

我們現(xiàn)在來看一下完整的示例,給大家演示一下如何使用接口里的靜態(tài)抽象成員這一特性。

看得懂了嗎?

支持的成員

支持 static abstract 的成員,除了字段、構造器(本來接口就沒有實例構造器一說)和索引器(索引器本身確實就沒有 static 一說)以外,別的都可以:

  • 屬性

  • 事件

  • 方法

  • 運算符

  • 類型轉換

用起來吧!

靜態(tài)抽象成員的顯式接口實現(xiàn)

和實例成員的實現(xiàn)方式一樣,如果你不得不隱藏接口成員,你可以使用基本的顯式接口實現(xiàn)的模式來完成,不過要記得帶上 static 關鍵字。

只不過,估計你第一次看到 INumber<A>.operator + 這種語法格式,可能會覺得有點奇妙。

探索 C# 10 的 static abstract 接口成員的評論 (共 條)

分享到微博請遵守國家法律
平阳县| 嵊泗县| 浏阳市| 永平县| 池州市| 本溪市| 肥乡县| 城口县| 清涧县| 云南省| 福泉市| 含山县| 南郑县| 临夏县| 临城县| 玉山县| 天津市| 保靖县| 荥经县| 闵行区| 岐山县| 三原县| 阳城县| 射洪县| 无极县| 浠水县| 资源县| 阿克苏市| 青铜峡市| 宾川县| 永修县| 赣州市| 手机| 凉山| 新郑市| 靖宇县| 广平县| 泗洪县| 建昌县| 道孚县| 辽宁省|