.NET 4.5Dodana sta bila dva nova vmesnika za zbirke, IReadOnlyList in IReadOnlyDictionary. Čeprav se ti vmesniki na prvi pogled zdijo tako vsakdanji, razkrivajo precej zapletene zgodbe o združljivosti za nazaj, interoperabilnosti in vlogi so-mutabilnosti.
IReadOnlyList in IReadOnlyDictionary sta dva vmesnika, ki sta si ju razvijalci .NET vedno želeli. Poleg zagotavljanja občutka simetrije (v nasprotju z zapisljivimi vmesniki) bi moral vmesnik samo za branje odpraviti implementacijo metod, ki vržejo le izjemo NotSupportedException in ne naredijo ničesar. Vse to ni bilo dokončano zaradi časovnih omejitev.
Naslednja priložnost je tukaj. NET 2.0. To Microsoftu omogoča, da upokoji šibko tipizirane zbirke in jih nadomesti z močno tipiziranimi vrstniškimi zbirkami. Vendar pa je ekipa bazne knjižnice[1] znova zamudila priložnost, da bi zagotovila seznam samo za branje, kot je zapisal Kit George,
Ker nameravamo zagotoviti privzeto implementacijo za problem, o katerem govorite z Joejem, namesto vmesnika nudimo osnovni razred ReadOnlyCollectionBase. Vendar razumem, zakaj so ljudje zadržani pri njegovi uporabi, ker ni močan tip. A z uvedbo generičnih izdelkov imamo zdaj tudi ReadOnlyCollection<T>, tako da ne dobite le enake funkcionalnosti, ampak tudi močan tip: odlično!
Ker ReadOnlyCollection <T>ni zapečaten razred, lahko po potrebi napišete svojo zbirko s polno hitrostjo. Ker so te zbirke, ki smo jih ustvarili za to, prilagodljive splošnim potrebam, ne nameravamo uvajati vmesnikov za isti koncept. Krzysztof Cwalina je prav tako izrazil svoje mnenje o tej temi,
Ne glede na to, ali se to sliši presenetljivo ali ne, IList in IList <T>sta dva vmesnika, ki ju nameravamo uporabiti za zbirke samo za branje. Oba imata boolovsko lastnost IsReadOnly, ki bi morala vrniti true, ko zbirka samo za branje implementira to lastnost. Razlog, da nočemo dodati povsem bralnega vmesnika, je, da menimo, da dodaja preveč nepotrebne kompleksnosti osnovni knjižnici. Upoštevajte, da v smislu kompleksnosti govorimo tako o tem novem vmesniku kot o njegovih uporabnikih.
Verjamemo, da če oblikovalec API-ja ne skrbi za preverjanje lastnosti IsReadOnly med izvajanjem in izjem, ki jih lahko sproži, je v tem primeru v redu uporabiti vmesnik IList; Če so pripravljeni ponuditi res čist, prilagojen API naenkrat, naj v tem primeru pokažejo implementacijo IList vmesnika in objavijo prilagojen API samo za branje. Slednje je značilno za zbirke, izpostavljene iz objektnega modela. Čeprav so se razvijalci pritoževali nad to situacijo, nove priložnosti, ki jih ponujajo generiki, daleč presegajo to ključno točko in težava je v . NET 4 je bil prej večinoma prezrt. Vendar je ta odločitev sprožila tudi nekatere odzive, o katerih bomo govorili kasneje.
Z vhodom. V runtime je bila dodana vznemirljiva nova funkcija v .NET 4. V prejšnji različici. .NET, ko vmesniki postanejo tipi, so ti vmesniki preveč omejeni. Na primer, tudi če stranka podeduje od osebe, ni mogoče posredovati objekta tipa IEnumerable <Customer>kot parameter funkciji tipa IEnumerable<Person>. Z dodajanjem kovariantne podpore je bila ta omejitev delno odpravljena.
Rečemo »delno«, ker bi morali v nekaterih primerih ljudje uporabljati vmesnik z bogatim API-jem hkrati, namesto da bi uporabljali IEnumerable vmesnik. Tudi če vmesnik IList ni kovarianten, bi moral biti vmesnik s seznamom samo za branje. Na žalost, . Ekipa za .NET osnovno knjižnico se je ponovno odločila, da tega spregleda ne bo obravnavala.
Potem sta uvedba WinRT in povratek COM-a spremenila vse. Interoperabilnost COM je bila nekoč tehnologija, ki so jo razvijalci uporabljali, kadar niso imeli druge izbire, zdaj pa je postala . Temelj .NET programiranja. In ker WinRT izpostavlja vmesnika IVectorView <T>in IMapView<K, torej V> vmesnike. .NET je treba ustrezno prilagoditi.
Ena zanimiva lastnost programa WinRT je napoved različnih, a podobnih API-jev za vsako razvojno platformo. Kot morda že veste, so vsa imena metod predstavljena s camelCased [2], medtem ko razvijalci v C++ in .NET uporabljajo imena metod kot PascalCased [3]. Druga, bolj drastična sprememba je samodejno preslikavanje vmesnikov C++ in .NET. Zato. Razvijalci .NET se ne rabijo ukvarjati z imenskim prostorom Windows.Foundation.Collections, le še naprej uporabljajo imenski prostor System.Collections.Generic. Vmesnika IVectorView <T>in IMapView<K, V> bodo med izvajanjem pretvorjena v vmesnike IReadOnlyList <T>in IReadOnlyDictionary<TKey, TValue> vmesnike.
Vredno je omeniti, da so ta imena vmesnikov v C++/WinRT do neke mere bolj natančna. Ti vmesniki se uporabljajo za predstavitev nekaterih pogledov zbirke, vendar vmesnik ne zagotavlja, da je sama zbirka nespremenljiva. Tudi med tistimi z izkušnjami. Pogosta napaka med razvijalci .NET je domneva, da je tip ReadOnlyCollection kopija nespremenljive zbirke, v resnici pa gre le za ovojnico aktivne zbirke (glej prispevek Andrewa Arnotta z istim imenom za več informacij o zbirkah samo za branje, zamrznjenih in nespremenljivih).
Čeprav ima vmesnik IList <T>vse iste člane kot vmesnik IReadOnlyList <T>in je mogoče vse sezname tipa IList <T>predstaviti kot sezname samo za branje, IList <T>ne podeduje IReadOnlyList<T>, kar je lahko zanimivo spoznati. je pojasnil Immo Landwerth,
Razlog, da deluje, je, da so ti vmesniki samo za branje čisti podnabori vmesnikov za branje in pisanje, kar se zdi razumna domneva. Na žalost ta predpostavka ne ustreza resničnosti, saj ima vsaka metoda na vsakem vmesniku na ravni metapodatkov svojo režo (kar omogoča delovanje eksplicitnih implementacij vmesnikov). Ali z drugimi besedami, edina možnost, da se uvede vmesnik samo za branje kot osnovni razred spremenljivke, je, da se vrnemo na . NET 2.0, torej ko so bili prvotno zasnovani. Ko je popolnoma razvit, je edina sprememba, ki jo lahko naredi, dodajanje kovariantnih in/ali inverter markerjev (predstavljenih kot "in" in "out" v VB in C#).
Na vprašanje, zakaj ni vmesnika IReadOnlyCollection<T>, je Immo odgovoril,
Razmišljali smo o tem dizajnu, vendar smo menili, da dodajanje tipa, ki ponuja le atribut Count, ne bi bistveno prispevalo k osnovni knjižnici. V ekipi za osnovno knjižnico verjamemo, da če API začne pri minus 1000, potem že zagotavljanje neke vrednosti ni dovolj, da bi upravičilo dodajanje. Razlog za dodajanje novih API-jev vključuje tudi stroške, na primer, razvijalci bodo imeli več konceptov za izbiro. Sprva smo mislili, da bo dodajanje te vrste kodo izboljšalo delovanje v določenih situacijah, kjer želite le narediti štetje in nato narediti nekaj zanimivega z njim. Na primer, množično dodajanje k obstoječi zbirki. Vendar pa smo v teh primerih spodbujali ljudi, naj uporabljajo samo vmesnik IEnumerable<T>, <T>v posebnem primeru pa obstaja instanca, ki implementira ICollection vmesnik. Ker so vse naše vgrajene vrste zbirk implementirale ta vmesnik, ni bilo izboljšave zmogljivosti v teh najpogostejših scenarijih. Mimogrede, <T>metoda razširitve Count() za IEnumerable to prav tako omogoča. Ti novi vmesniki so na voljo za . NET 4.5 in . NET for Windows 8。
Opombe k prevodu
[1] Knjižnica osnovnega razreda, okrajšano BCL. Za več informacij o osnovni knjižnici razredov prosimo, sodelujte na MSDN.
[2] CamelCased, nomenklatura grba, znana tudi kot spodnji kamelji primer. Oblika je, da se prva beseda začne z malo črko; Prva črka druge besede je napisana z veliko začetnico, na primer: firstName, lastName.
[3] PascalCased, Pascalova nomenklatura, znana tudi kot primer zgornje kamele. Format je tak, da je prva črka vsake besede napisana z veliko začetnico, na primer: FirstName, LastName, CamelCase. |