天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

.NET 4.5 中只讀集合接口的故事

  .NET 4.5中添加了兩個(gè)新的集合接口,IReadOnlyList和IReadOnlyDictionary。盡管這些接口表面上看起來(lái)是如此稀松平常,但是他們卻揭露了與向后兼容性、互操作性、以及協(xié)變的作用等有關(guān)的相當(dāng)復(fù)雜的故事。

  IReadOnlyList和IReadOnlyDictionary是.NET開(kāi)發(fā)者自始至終都想得到的接口。只讀接口除了提供某種對(duì)稱性之外,還應(yīng)消除那些什么都不做而只拋出NotSupportedException異常的方法。由于某些隨時(shí)間流逝已不可知的原因,此接口并未完成。

  接下來(lái)一次機(jī)會(huì)是在.NET 2.0中引入泛型。這使得微軟可以淘汰弱類型集合,并使用強(qiáng)類型變體替代它們。基類庫(kù)[1]團(tuán)隊(duì)再次錯(cuò)過(guò)了這個(gè)提供只讀列表(read-only list)的機(jī)會(huì),正如Kit George 所寫(xiě)的那樣

因?yàn)閷?duì)于你與Joe所談?wù)摰膯?wèn)題,我們打算提供一種缺省實(shí)現(xiàn),而不是給你一個(gè)接口,所以我們提供了ReadOnlyCollectionBase基類。然而,鑒于它不是強(qiáng)類型的,我能理解人們不愿使用它的原因。但隨著泛型的引入,我們現(xiàn)在同時(shí)擁有了ReadOnlyCollection<T>,所以你不僅獲得了同等的功能,而且就是強(qiáng)類型的:太棒了!

ReadOnlyCollection<T>不是密封類,因此如果需要可以隨意在此之上編寫(xiě)你自己的集合。自從我們?yōu)榇藙?chuàng)作的這些集合可適合一般需求以來(lái),我們尚沒(méi)有計(jì)劃為與此相同的概念引入接口。

  Krzysztof Cwalina也對(duì)此主題進(jìn)行了評(píng)論,

無(wú)論這聽(tīng)起來(lái)令人驚訝與否,但是IList和IList<T>是我們所期望的只讀集合接口。它們都擁有IsReadOnly布爾型屬性,當(dāng)某個(gè)只讀集合實(shí)現(xiàn)此屬性后應(yīng)返回true。我們不想添加純粹的只讀接口的原因是,我們覺(jué)得它會(huì)給基類庫(kù)添加太多不必要的復(fù)雜性。請(qǐng)注意,就復(fù)雜性而言,我們既指此新接口又指其消費(fèi)者。

我們覺(jué)得API的設(shè)計(jì)者們要么是并不關(guān)心在運(yùn)行時(shí)檢查IsReadOnly屬性、及其可能拋出的異常,在這種情況下使用IList接口就不錯(cuò),要么他們?cè)敢馓峁┮粋€(gè)真正整潔的自定義API,在這種情況下他們應(yīng)顯示實(shí)現(xiàn)IList接口、并公布自定義的簡(jiǎn)潔的只讀API。對(duì)于從對(duì)象模型中公開(kāi)的集合而言,后者是種典型方式。

  盡管開(kāi)發(fā)曾抱怨此種情況,由于泛型所提供的新機(jī)會(huì)遠(yuǎn)遠(yuǎn)大于這個(gè)癥結(jié),因此該問(wèn)題在.NET 4以前很大程度上被忽視了。然而,此決定也引發(fā)了一些反響,我們將在稍后討論。

  隨著在.NET 4中一個(gè)令人興奮的新功能被添加到運(yùn)行時(shí)。當(dāng)早期版本的.NET接口出現(xiàn)在類型中時(shí),那些接口是被過(guò)度限制的。例如,即使Customer繼承自Person,也無(wú)法將類型為IEnumerable<Customer>的對(duì)象作為參數(shù)類型為IEnumerable<Person>的函數(shù)的參數(shù)使用。隨著協(xié)變支持的添加,該限制才得以部分解除。

  我們之所以說(shuō)“部分”,是因?yàn)樵谀承┣榫跋拢鄬?duì)于IEnumerable接口而言,人們更愿意使用一個(gè)具有豐富API的接口。而且當(dāng)IList接口不支持協(xié)變的時(shí)候,至少該有一個(gè)只讀列表接口。不幸的是,.NET基類庫(kù)團(tuán)隊(duì)再次決定不解決這個(gè)疏忽。

  接著,WinRT的引入和COM的死灰復(fù)燃改變了一切。COM互操作性曾是開(kāi)發(fā)者在別無(wú)選擇的情況下才使用的一種技術(shù),但現(xiàn)已成為.NET編程的基石。而且由于WinRT公開(kāi)了IVectorView<T>IMapView<K, V>接口,因此.NET必須與時(shí)俱進(jìn)。

  WinRT計(jì)劃中一個(gè)頗為有趣的功能是,為每個(gè)開(kāi)發(fā)平臺(tái)公布不同但功能類似的API。正如你可能已經(jīng)知道的,通過(guò)JavaScript開(kāi)發(fā)者的眼睛所看到的是,所有方法名都是駝峰式大小寫(xiě)(camelCased[2])表示的,而C++和.NET開(kāi)發(fā)者所看到方法則是以帕斯卡大小寫(xiě)(PascalCased[3])表示的。另一處更加劇烈的變化是,在C++與.NET的接口之間實(shí)現(xiàn)自動(dòng)映射。因此.NET開(kāi)發(fā)者無(wú)需處理Windows.Foundation.Collections命名空間,而是繼續(xù)使用System.Collections.Generic命名空間。IVectorView<T>和IMapView<K, V>這兩個(gè)接口會(huì)被運(yùn)行庫(kù)轉(zhuǎn)化為IReadOnlyList<T>IReadOnlyDictionary<TKey, TValue>

  值得注意的是,在C++/WinRT中的這些接口名在某定程度上是更準(zhǔn)確的。這些接口是用來(lái)表示針對(duì)某集合的一些視圖,但是接口并不確保該集合本身是不可變的。即使在那些經(jīng)驗(yàn)豐富的.NET開(kāi)發(fā)者中也很常見(jiàn)的一種錯(cuò)誤是,假設(shè)ReadOnlyCollection類型的對(duì)象是某個(gè)集合的不可變副本,其實(shí),事實(shí)上此對(duì)象僅僅是對(duì)某活動(dòng)集合的包裝(wrapper)(關(guān)于只讀、凍結(jié)、且不可變集合的詳細(xì)信息,請(qǐng)參閱Andrew Arnott的同名帖子)。

  當(dāng)?shù)弥M管IList<T>接口具有與IReadOnlyList<T>接口所有相同的成員、并且所有列表都可表示為只讀列表,而IList<T>卻不是繼承自IReadOnlyList<T>以后,有人可能會(huì)覺(jué)得很有趣。Immo Landwerth解釋說(shuō)

這看起來(lái)是個(gè)合理的假設(shè),它之所以能工作是因?yàn)槟切┲蛔x接口是可讀寫(xiě)接口的純粹子集。不幸的是,此假設(shè)與預(yù)期不符,因?yàn)樵谠獢?shù)據(jù)級(jí)別上位于每個(gè)接口上的每個(gè)方法都有其自己的槽(這使得顯式接口實(shí)現(xiàn)得以工作)。

  或者換言之,他們必須將只讀接口作為那些可變種類的基類引入的唯一機(jī)會(huì)就是退回到.NET 2.0,即它們最初被構(gòu)思出來(lái)的時(shí)候。一旦放虎歸山,對(duì)其能做的唯一改變就是添加協(xié)變和/或逆變標(biāo)記(在VB和C#中表示為“in”和“out”)。

  當(dāng)被問(wèn)及為什么沒(méi)有IReadOnlyCollection<T>接口時(shí),Immo回答說(shuō),

我們?cè)紤]過(guò)這個(gè)設(shè)計(jì),但是我們覺(jué)得加入一個(gè)提供僅有Count屬性的類型對(duì)于基類庫(kù)而言不會(huì)增加很多價(jià)值。在基類庫(kù)團(tuán)隊(duì)中,我們認(rèn)為,如果一個(gè)API從負(fù)1000點(diǎn)開(kāi)始,那么即使能提供一些價(jià)值也不足以證明可被添加。添加新API的理由也包括成本,例如,開(kāi)發(fā)者會(huì)擁有更多可供選擇的概念。起初我們認(rèn)為,添加這個(gè)類型將使得代碼在某些場(chǎng)景(你只想獲得計(jì)數(shù),然后對(duì)它做一些有趣的東西)下獲得更好的性能。例如,批量添加到現(xiàn)有集合。然而,在這些場(chǎng)景下,我們鼓勵(lì)人們僅采用一個(gè)IEnumerable<T>接口,而且對(duì)于擁有實(shí)現(xiàn)了ICollection<T>接口的實(shí)例的特殊情況也是如此。自從所有我們的內(nèi)建集合類型實(shí)現(xiàn)了此接口之后,然而在那些最常見(jiàn)的情況下并未沒(méi)有獲得任何性能收益。順便說(shuō)一下,針對(duì)IEnumerable<T>的擴(kuò)展方法Count()同樣可以完成此功能。

  這些新接口可用于.NET 4.5和.NET for Windows 8。

  譯注

  [1] 基類庫(kù),Base Class Library,縮寫(xiě)為BCL。有關(guān)基類庫(kù)的更多信息,請(qǐng)參與MSDN

  [2] camelCased,駝峰式命名法,又稱小駝峰式命名法(lower camel case)。格式為,第一個(gè)單字以小寫(xiě)字母開(kāi)始;第二個(gè)單字的首字母大寫(xiě),例如:firstName、lastName。

  [3] PascalCased,帕斯卡命名法,又稱大駝峰式命名法(upper camel case)。格式為,每一個(gè)單字的首字母都采用大寫(xiě)字母,例如:FirstName、LastName、CamelCase。

  查看英文原文:The Story of Read-Only Collection Interfaces in .NET

NET技術(shù).NET 4.5 中只讀集合接口的故事,轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 6080YYY午夜理论片在线观看 | 中文字幕精品无码一区二区 | 九九热视频 这里有精品 | 色多多污污在线播放免费 | 精品国产麻豆免费人成网站 | 国产视频a在线观看v | 久久综合中文字幕佐佐木希 | 亚洲大码熟女在线 | 吸奶舔下面| 一个人免费观看完整视频日本 | 色中色最新地址登陆 | 三级网站视频 | 久久伊人青青 | 国产日韩精品一区二区在线观看 | 果冻传媒在线播放 免费观看 | 欧美亚洲视频在线二区 | 影音先锋色小姐 | 5G在线观看免费年龄确认 | 亚洲欭美日韩颜射在线二 | 王晶经典三级 | 恋夜秀场支持安卓版全部视频国产 | 超大号黑吊magnet | 草神被爆漫画羞羞漫画 | 精品国产人妻国语 | 亚洲国产精品嫩草影院久久 | 国产在线精品亚洲第1页 | 巨爆乳中文字幕爆乳区 | 国产在线一区观看 | 一本之道高清在线3线观看 一本之道高清视频在线观看 | 99视频在线精品免费观看18 | 无码日韩人妻精品久久蜜桃免费 | 狠狠干.in | 琪琪婷婷五月色综合久久 | 亚洲欧美高清在线精品一区 | 精品福利一区 | 精品一区二区三区高清免费观看 | 天天国产在线精品亚洲 | GOGOGO高清在线播放韩国 | 亚洲国产在线2o20 | 美女被打开了屁股进去的视频 | 乱叫抽搐流白浆免费视频 |