.NET 4.5Pridėtos dvi naujos rinkinio sąsajos – IReadOnlyList ir IReadOnlyDictionary. Nors šios sąsajos iš pirmo žvilgsnio gali atrodyti tokios kasdieniškos, jos atskleidžia gana sudėtingas istorijas apie atgalinį suderinamumą, sąveikumą ir komutacijos vaidmenį.
IReadOnlyList ir IReadOnlyDictionary yra dvi sąsajos, kurias .NET kūrėjai visada norėjo turėti. Be tam tikro simetrijos jausmo (priešingai nei rašomos sąsajos), tik skaitoma sąsaja turėtų pašalinti metodų, kurie tik pateikia NotSupportedException išimtį ir nieko nedaro, įgyvendinimą. Visa tai nebuvo baigta dėl laiko trūkumo.
Kita galimybė yra. GRYNASIS 2.0. Tai leidžia "Microsoft" atsisakyti silpnai įvestų rinkinių ir pakeisti juos stipriai įvestais lygiaverčiais rinkiniais. Tačiau bazinės bibliotekos[1] komanda vėl praleido progą pateikti tik skaitomą sąrašą, kaip rašė Kit George:
Kadangi ketiname pateikti numatytąjį problemos, apie kurią kalbate su Joe, įgyvendinimą, o ne sąsają, pateikiame ReadOnlyCollectionBase bazinę klasę. Tačiau suprantu, kodėl žmonės nenori jo naudoti, nes tai nėra stiprus tipas. Tačiau pristačius generinius vaistus, dabar turime ir "ReadOnlyCollection<T>", kad gautumėte ne tik tą patį funkcionalumą, bet ir stiprų tipą: puiku!
Kadangi "ReadOnlyCollection<T>" nėra uždara klasė, jei reikia, galite rašyti savo kolekciją visu greičiu. Kadangi šios kolekcijos, kurias sukūrėme šiam tikslui, yra pritaikomos bendriems poreikiams, neplanuojame pristatyti sąsajų tai pačiai koncepcijai. Krzysztofas Cwalina taip pat išreiškė savo nuomonę šia tema,
Nesvarbu, ar tai skamba stebina, ar ne, IList ir IList <T>yra dvi sąsajos, kurias ketiname naudoti tik skaitymo rinkiniams. Jie abu turi loginę ypatybę IsReadOnly, kuri turėtų grąžinti true, kai tik skaitomas rinkinys įdiegia šią ypatybę. Priežastis, kodėl nenorime pridėti grynos tik skaitymo sąsajos, yra ta, kad manome, kad ji prideda per daug nereikalingo sudėtingumo bazinei bibliotekai. Atkreipkite dėmesį, kad sudėtingumo požiūriu kalbame ir apie šią naują sąsają, ir apie jos vartotojus.
Manome, kad jei API dizaineriui nerūpi tikrinti IsReadOnly ypatybę vykdymo metu ir išimtis, kurias ji gali mesti, tokiu atveju galima naudoti IList sąsają; Jei jie nori vienu ypu pateikti tikrai švarią pasirinktinę API, tokiu atveju jie turėtų parodyti IList sąsajos įgyvendinimą ir paskelbti pritaikytą tik skaitymo API. Pastarasis būdingas kolekcijoms, eksponuojamoms iš objekto modelio. Nors kūrėjai skundėsi šia situacija, naujos generinių vaistų teikiamos galimybės gerokai nusveria šią esmę ir problema yra . NET 4 anksčiau buvo iš esmės ignoruojamas. Tačiau šis sprendimas taip pat sukėlė tam tikrų reakcijų, kurias aptarsime vėliau.
Su į. Į vykdymo laiką įtraukta įdomi nauja .NET 4 funkcija. Ankstesnėje versijoje. .NET, kai sąsajos tampa tipais, tos sąsajos yra pernelyg apribotos. Pavyzdžiui, net jei klientas paveldi iš asmens, neįmanoma perduoti IEnumerable tipo objekto <Customer>kaip parametro IEnumerable tipo funkcijai<Person>. Pridėjus kovarianto palaikymą, šis apribojimas buvo iš dalies panaikintas.
Mes sakome "iš dalies", nes kai kuriais atvejais žmonės turėtų naudoti tam tikrą sąsają su turtinga API iš karto, o ne naudoti IEnumerable sąsają. Net jei IList sąsaja nėra kovariantinė, turėtų būti tik skaitomo sąrašo sąsaja. Deja, . .NET bazinės bibliotekos komanda vėl nusprendė nespręsti šios priežiūros.
Tada WinRT įvedimas ir COM sugrįžimas viską pakeitė. COM sąveika kadaise buvo technologija, kurią kūrėjai naudodavo neturėdami kito pasirinkimo, tačiau ji tapo . Kertinis .NET programavimo akmuo. Kadangi "WinRT" atskleidžia "IVectorView<T>" ir "IMapView<K, V> sąsajas. .NET taip pat turi būti atitinkamai pakoreguotas.
Viena įdomi WinRT programos savybė yra skirtingų, bet panašių API kiekvienai kūrimo platformai paskelbimas. Kaip jau tikriausiai žinote, visi metodų pavadinimai yra pavaizduoti camelCased [2], o C++ ir .NET kūrėjai mato metodų pavadinimus kaip PascalCased [3]. Kitas drastiškesnis pokytis yra automatinis C++ ir .NET sąsajų susiejimas. Todėl. .NET kūrėjams nereikia dirbti su Windows.Foundation.Collections vardų sritimi, tiesiog toliau naudokite System.Collections.Generic vardų sritį. IVectorView <T>ir IMapView<K, V> sąsajos bus konvertuotos <T>atitinkamai į IReadOnlyList sąsajas ir IReadOnlyDictionary<TKey, TValue> sąsajas.
Verta paminėti, kad šie C++/WinRT sąsajos pavadinimai tam tikru mastu yra tikslesni. Šios sąsajos naudojamos kai kuriems rinkinio rodiniams pavaizduoti, tačiau sąsaja neužtikrina, kad pats rinkinys būtų nekintamas. Net tarp patyrusių. Dažna .NET kūrėjų klaida yra manyti, kad ReadOnlyCollection tipas yra nekintamo rinkinio kopija, tačiau iš tikrųjų tai yra tik aktyvios kolekcijos įvyniojimas (daugiau informacijos apie tik skaitomus, užšaldytus ir nekintančius rinkinius rasite Andrew Arnott to paties pavadinimo įraše).
Nors IList <T>sąsaja turi visus tuos pačius narius kaip ir IReadOnlyList <T>sąsaja, ir visi IList tipo <T>sąrašai gali būti pateikiami kaip tik skaitomi sąrašai, IList <T>nepaveldi iš IReadOnlyList<T>, apie kurį gali būti įdomu sužinoti. Immo Landwerth paaiškino:
Priežastis, kodėl tai veikia, yra ta, kad tos tik skaitymo sąsajos yra gryni skaitymo ir rašymo sąsajų poaibiai, o tai atrodo pagrįsta prielaida. Deja, ši prielaida neatitinka tikrovės, nes kiekvienas metodas kiekvienoje sąsajoje metaduomenų lygmenyje turi savo lizdą (todėl aiškios sąsajos įgyvendinimas veikia). Arba kitaip tariant, vienintelė galimybė įvesti tik skaitymo sąsają kaip kintamosios klasės bazinę klasę yra grįžti prie . NET 2.0, t.y. kai jie buvo sumanyti. Kai jis bus visiškai išleistas, vienintelis pakeitimas, kurį jis gali padaryti, yra pridėti kovariantinius ir (arba) keitiklio žymeklius (VB ir C# vaizduojami kaip "in" ir "out").
Paklaustas, kodėl nėra IReadOnlyCollection <T>sąsajos, Immo atsakė:
Mes svarstėme šį dizainą, bet manėme, kad pridėjus tipą, kuriame buvo tik atributas Count, bazinei bibliotekai nebus pridėta daug vertės. Bazinės bibliotekos komandoje manome, kad jei API prasideda nuo minus 1000, net ir tam tikros vertės nepakanka, kad būtų galima pateisinti pridėjimą. Naujų API pridėjimo pagrindimas taip pat apima išlaidas, pavyzdžiui, kūrėjai turės daugiau koncepcijų, iš kurių galės rinktis. Iš pradžių manėme, kad pridėjus šį tipą kodas veiks geriau tam tikrais scenarijais, kai tiesiog norite suskaičiuoti ir tada padaryti ką nors įdomaus. Pavyzdžiui, masinis įtraukimas į esamą rinkinį. Tačiau šiuose scenarijuose mes skatinome žmones naudoti tik IEnumerable <T>sąsają ir <T>ypatingu atveju, kai turite egzempliorių, kuris įgyvendina ICollection sąsają. Kadangi visi mūsų integruoti kolekcijų tipai įdiegė šią sąsają, dažniausiai pasitaikančiais scenarijais našumas nepadidėjo. Beje, <T>IEnumerable išplėtimo metodas Count() taip pat gali tai padaryti. Šios naujos sąsajos yra prieinamos . NET 4.5 ir . NET Windows 8。
Vertimo pastabos
[1] Bazinės klasės biblioteka, sutrumpintai BCL. Norėdami gauti daugiau informacijos apie bazinės klasės biblioteką, dalyvaukite MSDN.
[2] kupranugarisKorpusas, kupros nomenklatūra, taip pat žinomas kaip apatinis kupranugarių atvejis. Formatas yra toks, kad pirmasis žodis prasideda mažąja raide; Pirmoji antrojo žodžio raidė rašoma didžiąja raide, pavyzdžiui: vardas, pavardė.
[3] PascalCased, Paskalio nomenklatūra, taip pat žinoma kaip viršutinė kupranugarių raidė. Formatas yra toks, kad kiekvieno žodžio pirmoji raidė rašoma didžiosiomis raidėmis, pavyzdžiui: Vardas, Pavardė, CamelCase. |