.NET 4,5Ir pievienotas divas jaunas kolekcijas saskarnes, IReadOnlyList un IReadOnlyDictionary. Lai gan šīs saskarnes virspusēji var šķist tik ikdienišķas, tās atklāj diezgan sarežģītus stāstus par atpakaļsaderību, sadarbspēju un komutējamības lomu.
IReadOnlyList un IReadOnlyDictionary ir divas saskarnes, kuras .NET izstrādātāji vienmēr ir vēlējušies. Papildus simetrijas sajūtas nodrošināšanai (atšķirībā no rakstāmiem interfeisiem), tikai lasāmam interfeisam vajadzētu novērst tādu metožu ieviešanu, kas tikai izmet NotSupportedException izņēmumu un neko nedara. Tas viss netika pabeigts laika ierobežojumu dēļ.
Nākamā iespēja ir iekšā. NETO 2.0. Tas ļauj korporācijai Microsoft atteikties no vāji ierakstītām kolekcijām un aizstāt tās ar stipri ierakstītām vienādranga kolekcijām. Tomēr bāzes bibliotēkas[1] komanda atkal palaida garām iespēju nodrošināt tikai lasāmu sarakstu, kā rakstīja Kit George:
Tā kā mēs plānojam nodrošināt noklusējuma ieviešanu problēmai, par kuru jūs runājat ar Džo, tā vietā, lai sniegtu saskarni, mēs nodrošinām ReadOnlyCollectionBase bāzes klasi. Tomēr es varu saprast, kāpēc cilvēki to nelabprāt izmanto, jo tas nav spēcīgs veids. Bet, ieviešot ģenēriskos līdzekļus, mums tagad ir arī ReadOnlyCollection<T>, lai jūs iegūtu ne tikai tādu pašu funkcionalitāti, bet arī spēcīgu tipu: lieliski!
Tā kā ReadOnlyCollection <T>nav aizzīmogota klase, ja nepieciešams, varat rakstīt savu kolekciju pilnā ātrumā. Tā kā šīs kolekcijas, ko mēs esam izveidojuši, ir pielāgojamas vispārējām vajadzībām, mēs neplānojam ieviest saskarnes šai pašai koncepcijai. Krzysztof Cwalina arī pauda savu viedokli par šo tēmu,
Neatkarīgi no tā, vai tas izklausās pārsteidzoši vai nē, IList un IList <T>ir divas saskarnes, kuras mēs plānojam izmantot tikai lasāmām kolekcijām. Abiem ir IsReadOnly būla rekvizīts, kam vajadzētu atgriezties true, kad tikai lasāmā kolekcija ievieš šo rekvizītu. Iemesls, kāpēc mēs nevēlamies pievienot tīru tikai lasāmu interfeisu, ir tas, ka mēs uzskatām, ka tas rada pārāk daudz nevajadzīgu sarežģītību bāzes bibliotēkai. Ņemiet vērā, ka sarežģītības ziņā mēs atsaucamies gan uz šo jauno saskarni, gan uz tās patērētājiem.
Mēs uzskatām, ka, ja API dizaineris nerūpējas par IsReadOnly rekvizīta pārbaudi izpildlaikā un izņēmumiem, ko tas var radīt, tad šajā gadījumā ir pareizi izmantot IList interfeisu; Ja viņi vēlas nodrošināt patiešām tīru pielāgotu API vienā piegājienā, tad šajā gadījumā viņiem vajadzētu parādīt IList saskarnes ieviešanu un publicēt pielāgotu tikai lasāmu API. Pēdējais ir raksturīgs kolekcijām, kas eksponētas no objekta modeļa. Lai gan izstrādātāji ir sūdzējušies par šo situāciju, jaunās iespējas, ko sniedz ģenēriskie medikamenti, ievērojami pārsniedz šo būtību, un problēma ir . NET 4 iepriekš lielā mērā tika ignorēts. Tomēr šis lēmums izraisīja arī dažas reakcijas, kuras mēs apspriedīsim vēlāk.
Ar iekšu. Izpildlaikam ir pievienota aizraujoša jauna .NET 4 funkcija. Iepriekšējā versijā. .NET, kad saskarnes kļūst par tipiem, šīs saskarnes ir pārāk ierobežotas. Piemēram, pat ja klients manto no personas, nav iespējams nodot IEnumerable tipa objektu <Customer>kā parametru IEnumerable tipa funkcijai<Person>. Pievienojot kovariantu atbalstu, šis ierobežojums tika daļēji atcelts.
Mēs sakām "daļēji", jo dažos gadījumos cilvēkiem vajadzētu izmantot kādu saskarni ar bagātīgu API uzreiz, nevis izmantot IEnumerable interfeisu. Pat ja IList interfeiss nav kovariants, vajadzētu būt tikai lasāmam saraksta interfeisam. Diemžēl, . .NET bāzes bibliotēkas komanda atkal ir nolēmusi nerisināt šo pārraudzību.
Tad WinRT ieviešana un COM atgriešanās mainīja visu. COM sadarbspēja kādreiz bija tehnoloģija, ko izstrādātāji izmantoja, kad viņiem nebija citas izvēles, bet tā ir kļuvusi par . .NET programmēšanas stūrakmens. Un tā kā WinRT atklāj IVectorView <T>un IMapView<K, V> saskarnes. Attiecīgi jāpielāgo arī .NET.
Viena interesanta WinRT programmas iezīme ir paziņojums par dažādiem, bet līdzīgiem API katrai izstrādes platformai. Kā jūs jau zināt, visus metožu nosaukumus attēlo camelCased [2], bet C++ un .NET izstrādātāji redz metožu nosaukumus kā PascalCased [3]. Vēl viena radikālāka pārmaiņa ir automātiskā kartēšana starp C++ un .NET saskarnēm. Tāpēc. .NET izstrādātājiem nav jāstrādā ar Windows.Foundation.Collections nosaukumvietu, vienkārši turpiniet izmantot System.Collections.Generic nosaukumvietu. IVectorView <T>un IMapView<K, V> saskarnes izpildlaikā tiks pārveidotas attiecīgi par IReadOnlyList <T>saskarnēm un IReadOnlyDictionary<TKey, TValue> saskarnēm.
Ir vērts atzīmēt, ka šie interfeisa nosaukumi C++/WinRT zināmā mērā ir precīzāki. Šie interfeisi tiek izmantoti, lai attēlotu dažus kolekcijas skatus, bet interfeiss nenodrošina, ka pati kolekcija ir nemainīga. Pat starp tiem, kuriem ir pieredzējuši. Izplatīta kļūda .NET izstrādātāju vidū ir pieņemt, ka ReadOnlyCollection tips ir nemainīgas kolekcijas kopija, bet patiesībā tas ir tikai aktīvas kolekcijas iesaiņojums (skatiet Andrew Arnott ierakstu ar tādu pašu nosaukumu, lai iegūtu plašāku informāciju par tikai lasāmām, iesaldētām un nemainīgām kolekcijām).
Lai gan IList <T>interfeisam ir visi tie paši dalībnieki kā IReadOnlyList <T>interfeisam, un visus IList tipa <T>sarakstus var attēlot kā tikai lasāmus sarakstus, IList <T>nepārmanto no IReadOnlyList<T>, par ko var būt interesanti uzzināt. Immo Landwerth paskaidroja:
Iemesls, kāpēc tas darbojas, ir tāpēc, ka šīs tikai lasāmās saskarnes ir tīras lasīšanas-rakstīšanas interfeisu apakškopas, kas šķiet saprātīgs pieņēmums. Diemžēl šis pieņēmums neatbilst realitātei, jo katrai metodei katrā saskarnē metadatu līmenī ir savs slots (kas padara skaidru saskarnes ieviešanu darboties). Citiem vārdiem sakot, vienīgā iespēja ieviest tikai lasāmu interfeisu kā mainīgās klases bāzes klasi ir atgriezties pie . NET 2.0, t.i., kad tie sākotnēji tika iecerēti. Kad tas ir pilnībā ieviests, vienīgās izmaiņas, ko tas var veikt, ir pievienot kovariantu un/vai invertora marķierus (VB un C# attēloti kā "in" un "out").
Uz jautājumu, kāpēc nav IReadOnlyCollection <T>saskarnes, Immo atbildēja:
Mēs apsvērām šo dizainu, bet mēs uzskatījām, ka tāda tipa pievienošana, kas nodrošina tikai atribūtu Count, neradīs lielu vērtību bāzes bibliotēkai. Bāzes bibliotēkas komandā mēs uzskatām, ka, ja API sākas ar mīnus 1000, tad pat ar kādas vērtības nodrošināšanu nepietiek, lai attaisnotu pievienošanu. Jaunu API pievienošanas pamatojums ietver arī izmaksas, piemēram, izstrādātājiem būs vairāk koncepciju, no kurām izvēlēties. Sākumā mēs domājām, ka šāda tipa pievienošana padarīs kodu labāku noteiktos scenārijos, kad jūs vienkārši vēlaties iegūt skaitu un pēc tam darīt kaut ko interesantu ar to. Piemēram, lielapjoma pievienošana esošai kolekcijai. Tomēr šajos scenārijos mēs esam mudinājuši cilvēkus izmantot tikai IEnumerable <T><T>interfeisu un īpašo gadījumu, kad ir instance, kas ievieš ICollection interfeisu. Tā kā visi mūsu iebūvētie kolekciju veidi ieviesa šo interfeisu, šajos visbiežāk sastopamajos scenārijos nav bijis veiktspējas pieauguma. Starp citu, <T>to var izdarīt arī IEnumerable paplašināšanas metode Count(). Šīs jaunās saskarnes ir pieejamas . NET 4.5 un . NET operētājsistēmai Windows 8。
Tulkošanas piezīmes
[1] Bāzes klases bibliotēka, saīsināti kā BCL. Lai iegūtu papildinformāciju par pamatklases bibliotēku, lūdzu, piedalieties MSDN.
[2] CamelCased, kupra nomenklatūra, pazīstama arī kā apakšējā kamieļu lieta. Formāts ir tāds, ka pirmais vārds sākas ar mazo burtu; Otrā vārda pirmais burts ir rakstīts ar lielo burtu, piemēram: vārds, uzvārds.
[3] PascalCased, Paskāla nomenklatūra, pazīstama arī kā augšējā kamieļu lieta. Formāts ir tāds, ka katra vārda pirmais burts tiek rakstīts ar lielo burtu, piemēram: Vārds, Uzvārds, CamelCase. |