.NET 4.5Két új gyűjteményfelület, az IReadOnlyList és az IReadOnlyDictionary került hozzá. Bár ezek az interfészek elsőre hétköznapinak tűnhetnek, meglehetősen összetett történeteket tárnak fel a visszafelé kompatibilitásról, az interoperabilitásról és a ko-mutálóság szerepéről.
Az IReadOnlyList és az IReadOnlyDictionary két olyan interfész, amelyet a .NET fejlesztők mindig is szerettek volna. A csak olvasható interfész nemcsak szimmetriaérzetet ad (ellentétben a írható interfészekkel), hanem megszüntetnie kell azokat a metódusok megvalósítását, amelyek csak NotSupportedException kivételt adnak és semmit sem csinálnak. Mindez időkorlátok miatt nem valósult meg.
A következő lehetőség eljött. NET 2.0. Ez lehetővé teszi a Microsoft számára, hogy a gyengén típusozott gyűjteményeket vonulja vissza, és azokat erősen típusozott társas gyűjteményekkel helyettesítse. Azonban az alapkönyvtár[1] csapat ismét elszalasztotta a lehetőséget, hogy csak olvasható listát készítsen, ahogy Kit George írta,
Mivel eredetileg egy alapértelmezett implementációt szeretnénk biztosítani a problémára, ahelyett, hogy interfészt adnánk, hanem a ReadOnlyCollectionBase alaposztályt adjuk. Viszont megértem, miért vonakodnak az emberek használni, mert nem erős típus. De a generikák bevezetésével most már megvan a ReadOnlyCollection <T>is, így nemcsak ugyanazt a funkciót kapjátok, hanem egy erős típust is: nagyszerű!
Mivel a ReadOnlyCollection <T>nem zárt osztály, szükség esetén teljes sebességgel írhatod a saját gyűjteményedet. Mivel ezek a gyűjtemények, amelyeket erre készítettünk, alkalmazkodnak az általános igényekhez, nem tervezünk interfészeket bevezetni ehhez a koncepcióhoz. Krzysztof Cwalina szintén kifejezte véleményét erről a témáról:
Akár meglepőnek hangzik, akár nem, az IList és az IList <T>azok a két interfész, amelyeket csak olvasható gyűjteményekhez tervezünk használni. Mindkettőnek van IsReadOnly boolean tulajdonsága, amelynek true kell visszaadnia, ha egy csak olvasható gyűjtemény implementálja ezt a tulajdonságot. Azért nem szeretnénk kizárólag olvasható felületet hozzáadni, mert úgy érezzük, túl sok felesleges bonyolultságot ad az alapkönyvtárnak. Fontos megjegyezni, hogy összetettség szempontjából ezt az új felületet és annak fogyasztóit is említjük.
Úgy gondoljuk, hogy ha az API tervezőt nem érdekli, hogy futásidőben ellenőrizze az IsReadOnly tulajdonságot és az általa adott kivételeket, akkor ebben az esetben az IList interfészt használhatjuk; Ha hajlandóak egy igazán tiszta, egyedi API-t egyszerre biztosítani, akkor ebben az esetben meg kell mutatniuk az IList interfész megvalósítását, és kiadniuk kell egy személyre szabott, csak olvasható API-t. Ez utóbbi jellemző az objektummodellből kitett gyűjtemények esetében. Bár a fejlesztők panaszkodtak erre a helyzetre, az generikus modellek által kínált új lehetőségek messze felülmúlják ezt a lényeget, és a probléma a . A NET 4-et korábban nagyrészt figyelmen kívül hagyták. Ez a döntés azonban néhány reakciót is kiváltott, amelyekről később beszélünk.
A bejutással. Egy izgalmas új funkció került a .NET 4-hez a futásidőhöz. Egy korábbi verzióban. .NET, amikor az interfészek típussá válnak, ezek az interfészek túlzottan korlátozottak. Például, még ha az ügyfél is örököl a Személytől, nem lehetséges IEnumerable típusú <Customer>objektumot paraméterként átadni egy IEnumerable típusú függvénynek<Person>. A kovariáns támogatás hozzáadásával ezt a korlátozást részben feloldották.
Azért mondjuk "részlegesen", mert bizonyos esetekben valamilyen interfészt kell használni egy gazdag API-val egyszerre, nem pedig IEnumerable interfészt. Még ha az IList interfész nem is kovariáns, akkor is csak olvasható lista felületnek annak kell lennie. Sajnos, . A .NET báziskönyvtár csapata ismét úgy döntött, hogy nem foglalkozik ezzel a mulasztással.
Aztán a WinRT bevezetése és a COM visszatérése mindent megváltoztatott. A COM interoperabilitás egykor olyan technológia volt, amit a fejlesztők akkor használtak, amikor nem volt más választásuk, de mára egy . A .NET programozás alapköve. Mivel a WinRT kimutatja az IVectorView <T>és IMapView<K, V> interfészeket, ezért. A .NET-et is ennek megfelelően kell módosítani.
A WinRT program egyik érdekes jellemzője, hogy minden fejlesztőplatformhoz külön, de hasonló API-kat jelentenek be. Ahogy már tudod, minden metódusnevet camelCased [2] jelöl, míg a C++ és .NET fejlesztők PascalCased [3] módszerneveket látnak. Egy másik drasztikus változás az automatikus leképezés a C++ és .NET interfészek között. Ezért. A .NET fejlesztőknek nem kell a Windows.Foundation.Collections névtérrel foglalkozniuk, csak továbbra is a System.Collections.Generic névteret használják. Az IVectorView <T>és IMapView<K, V> interfészek a futás során IReadOnlyList <T>és IReadOnlyDictionary<TKey, TValue> interfésekre alakulnak.
Érdemes megjegyezni, hogy ezek a C++/WinRT interfésznevek bizonyos mértékig pontosabbak. Ezeket az interfészeket a gyűjtemény egyes nézeteinek megjelenítésére használják, de az interfész nem biztosítja, hogy maga a gyűjtemény változatlan legyen. Még a tapasztalt emberek között is. Gyakori hiba a .NET fejlesztők körében, hogy feltételezik, hogy a ReadOnlyCollection típus egy változatlan gyűjtemény másolata, de valójában csak egy aktív gyűjtemény csomagolása (lásd Andrew Arnott azonos című bejegyzését további információkért az csak olvasható, lefagyasztott és változatlan gyűjteményekről).
Bár az IList <T>interfész mind ugyanazokat a tagokat tartalmazza, mint az IReadOnlyList <T>interfészé, és minden IList típusú <T>lista csak olvasható listaként ábrázolható, az IList <T>nem örököl az IReadOnlyList-ből<T>, ami érdekes lehet megismerni. Immo Landwerth elmagyarázta,
Azért működik, mert ezek az csak olvasható interfészek tiszta részhalmazai az olvasás-írás interfészeknek, ami ésszerű feltételezésnek tűnik. Sajnos ez a feltételezés nem egyezik a valósággal, mivel minden metaadat szinten minden interfészen saját helyet foglal el (ami lehetővé teszi az explicit interfész megvalósítások működését). Más szóval, az egyetlen esély arra, hogy egy csak olvasási felületet bevezetjenek, mint valamilyen változó osztály alaposztályt, ha visszatérünk . NET 2.0, azaz amikor eredetileg megalkották. Miután teljesen kibontakozott, az egyetlen változtatás, ha hozzáadja a kovariáns és/vagy inverter jelölőket (VB és C# formátumban "be" és "out" jelzések).
Amikor megkérdezték, miért nincs IReadOnlyCollection <T>interfész, az Immo így válaszolt:
Ezt a tervet fontolgattuk, de úgy éreztük, hogy egy olyan típus hozzáadása, amely csak a Count attribútumot adja, nem hozna sokat az alapkönyvtárnak. Az alapkönyvtár csapatában úgy gondoljuk, hogy ha egy API mínusz 1000-nél indul, akkor még némi érték sem elég ahhoz, hogy hozzáadjuk. Az új API-k hozzáadásának indoklása egy költséget is tartalmaz, például a fejlesztők több fogalma közül választhatnak. Eleinte azt hittük, hogy ennek a típusnak a hozzáadása bizonyos helyzetekben jobban teljesít a kódot, ahol csak számolni akarsz, majd valami érdekeset csinálni vele. Például tömeges hozzáadás egy meglévő gyűjteményhez. Azonban ezekben a helyzetekben arra biztattuk az embereket, hogy csak az IEnumerable <T>felületet használják, és speciális esetben is, hogy <T>legyen egy példány, amely az ICollection interfészt valósítja meg. Mivel minden beépített gyűjteménytípusunk megvalósította ezt az interfészt, ezekben a leggyakoribb esetekben nem volt teljesítményjavulás. Egyébként <T>az IEnumerable kiterjesztési módszere, a Count() is képes erre. Ezek az új interfészek elérhetők . NET 4.5 és . NET for Windows 8。
Fordítási jegyzetek
[1] Alap osztálykönyvtár, rövidítve BCL. További információért az alap osztálykönyvtárról kérjük, vegyen részt az MSDN programon.
[2] CamelCased, púpos elnevezés, más néven alsó tevebőr. A formátum az, hogy az első szó kisbetűvel kezdődik; A második szó első betűje nagybetűvel van írva, például: keresztnév, vezetéknév.
[3] PascalCased, Pascal név, más néven felső tevebőr. A formátum az, hogy minden szó első betűje nagybetűvel van kiírva, például: Keresztnév, Vezetéknév, TeveCase. |