Acest articol este un articol oglindă al traducerii automate, vă rugăm să faceți clic aici pentru a sări la articolul original.

Vedere: 19672|Răspunde: 1

[Sursă] . .NET Povestea interfeței de colectare doar în citire

[Copiază linkul]
Postat pe 05.02.2018 14:28:10 | | |
.NET 4.5Au fost adăugate două noi interfețe de colecție, IReadOnlyList și IReadOnlyDictionary. Deși aceste interfețe pot părea atât de banale la prima vedere, ele dezvăluie povești destul de complexe despre compatibilitatea retroactivă, interoperabilitate și rolul comutabilității.

IReadOnlyList și IReadOnlyDictionary sunt două interfețe pe care dezvoltatorii .NET și le-au dorit mereu. Pe lângă faptul că oferă un anumit sentiment de simetrie (spre deosebire de interfețele scrizibile), o interfață doar pentru citire ar trebui să elimine implementarea metodelor care aruncă doar o excepție NotSupportedException și nu fac nimic. Toate acestea nu au fost finalizate din cauza constrângerilor de timp.

Următoarea oportunitate a venit. NET 2.0. Acest lucru permite Microsoft să retragă colecțiile slab tipate și să le înlocuiască cu colecții peer puternic tipate. Totuși, echipa de bază[1] a ratat din nou ocazia de a oferi o listă doar pentru citire, după cum a scris Kit George,

Deoarece intenționăm să oferim o implementare implicită pentru problema despre care vorbești cu Joe, în loc să oferim o interfață, oferim clasa de bază ReadOnlyCollectionBase. Totuși, pot înțelege de ce oamenii ezită să-l folosească pentru că nu este un tip puternic. Dar odată cu introducerea genericelor, avem acum și <T>ReadOnlyCollection, astfel încât nu doar că primești aceeași funcționalitate, ci și un tip puternic: grozav!

Deoarece ReadOnlyCollection <T>nu este o clasă sigilată, poți scrie propria colecție la capacitate maximă, dacă este necesar. Deoarece aceste colecții pe care le-am creat pentru acest scop sunt adaptabile la nevoi generale, nu intenționăm să introducem interfețe pentru același concept.

Krzysztof Cwalina și-a exprimat, de asemenea, opinia pe această temă,

Indiferent dacă acest lucru sună surprinzător sau nu, IList și IList <T>sunt cele două interfețe pe care intenționăm să le folosim pentru colecțiile doar în citire. Ambele au proprietatea booleană IsReadOnly, care ar trebui să returneze adevărată atunci când o colecție doar în citire implementează această proprietate. Motivul pentru care nu vrem să adăugăm o interfață doar pentru citire este că simțim că adaugă prea multă complexitate inutilă bibliotecii de bază. Rețineți că, în termeni de complexitate, ne referim atât la această nouă interfață, cât și la consumatorii săi.

Credem că, dacă designerul API nu este interesat să verifice proprietatea IsReadOnly la rulare și excepțiile pe care le poate genera, atunci este în regulă să folosească interfața IList în acest caz; Dacă sunt dispuși să ofere un API personalizat foarte curat dintr-o dată, atunci în acest caz ar trebui să arate implementarea interfeței IList și să publice un API personalizat doar pentru citire. Aceasta din urmă este tipică pentru colecțiile expuse din modelul obiectului.

Deși dezvoltatorii s-au plâns de această situație, noile oportunități oferite de generice depășesc cu mult această esență, iar problema este în . NET 4 a fost în mare parte ignorat înainte. Totuși, această decizie a stârnit și unele reacții, despre care vom discuta mai târziu.

Cu intratul. O funcție nouă și interesantă în .NET 4 a fost adăugată la runtime. Într-o versiune anterioară. .NET, când interfețele devin tipuri, aceste interfețe sunt excesiv de restricționate. De exemplu, chiar dacă Clientul moștenește de la Persoană, nu este posibil să se transmită un obiect de tip IEnumerable <Customer>ca parametru unei funcții de tip IEnumerabil<Person>. Odată cu adăugarea suportului covariant, această restricție a fost parțial ridicată.

Spunem "parțial" pentru că, în unele cazuri, oamenii ar trebui să folosească o interfață cu un API bogat deodată, în loc să folosească o interfață IEnumerabil. Chiar dacă interfața IList nu este covariantă, o interfață cu liste doar citire ar trebui să fie. Din păcate, . Echipa bibliotecii de bază .NET a decis din nou să nu abordeze această scăpare.

Apoi introducerea WinRT și revenirea COM au schimbat totul. Interoperabilitatea COM a fost odată o tehnologie pe care dezvoltatorii o foloseau atunci când nu aveau altă opțiune, dar a devenit o tehnologie . Piatra de temelie a programării .NET. Și, deoarece WinRT expune <T>interfețele IVectorView și IMapView<K, V>, prin urmare. .NET trebuie, de asemenea, ajustat corespunzător.

O caracteristică interesantă a programului WinRT este anunțul unor API-uri diferite, dar similare, pentru fiecare platformă de dezvoltare. După cum probabil știi deja, toate numele metodelor sunt reprezentate prin camelCased [2], în timp ce dezvoltatorii C++ și .NET văd numele metodelor ca PascalCased [3]. O altă schimbare mai drastică este maparea automată între interfețele C++ și .NET. Prin urmare. Dezvoltatorii .NET nu trebuie să se ocupe de spațiul de nume Windows.Foundation.Collections, ci doar să continue să folosească spațiul de nume System.Collections.Generic. <T>Interfețele IVectorView și IMapView<K, V> vor fi convertite de runtime în <T>interfețe IReadOnlyList și interfețe IReadOnlyDictionary<TKey, TValue>, respectiv.

Merită menționat că aceste nume de interfață în C++/WinRT sunt mai precise într-o anumită măsură. Aceste interfețe sunt folosite pentru a reprezenta unele vederi ale unei colecții, dar interfața nu asigură că colecția în sine este imuabilă. Chiar și printre cei cu experiență. O greșeală frecventă printre dezvoltatorii .NET este să presupună că tipul ReadOnlyCollection este o copie a unei colecții imuabile, dar de fapt este doar un wrapper pentru o colecție activă (vezi postarea lui Andrew Arnott cu același nume pentru mai multe informații despre colecțiile doar în citire, congelate și imuabile).

Deși <T>interfața IList are toți aceiași membri ca <T>interfața IReadOnlyList, iar toate listele de tip IList <T>pot fi reprezentate ca liste doar pentru citire, IList <T>nu moștenește din IReadOnlyList<T>, ceea ce poate fi interesant de aflat. Immo Landwerth a explicat,

Motivul pentru care funcționează este că acele interfețe doar în citire sunt pur subseturi ale interfețelor de citire-scriere, ceea ce pare o presupunere rezonabilă. Din păcate, această presupunere nu corespunde realității, deoarece fiecare metodă de pe fiecare interfață la nivel de metadate are propriul său slot (ceea ce face ca implementările explicite de interfață să funcționeze).

Sau, cu alte cuvinte, singura șansă de a introduce o interfață doar în citire ca o clasă de bază variabilă este să revenim la . NET 2.0, adică când au fost concepute inițial. Odată ce este complet implementat, singura modificare pe care o poate face este adăugarea de markere covariante și/sau de invertor (reprezentate ca "in" și "out" în VB și C#).

Când am fost întrebat de ce nu există <T>o interfață IReadOnlyCollection, Immo a răspuns,

Am luat în considerare acest design, dar am considerat că adăugarea unui tip care oferă doar atributul Count nu ar adăuga prea multă valoare bibliotecii de bază. În echipa bibliotecii de bază, credem că dacă un API începe de la minus 1000, atunci chiar și oferirea unei anumite valori nu este suficientă pentru a justifica adăugarea. Rațiunea pentru adăugarea de noi API-uri include și un cost, de exemplu, dezvoltatorii vor avea mai multe concepte din care să aleagă. La început am crezut că adăugarea acestui tip va face ca codul să performeze mai bine în anumite situații în care vrei doar să obții un număr și apoi să faci ceva interesant cu el. De exemplu, adaugă în masă la o colecție existentă. Totuși, în aceste scenarii, am încurajat oamenii să folosească doar <T>interfața IEnumerable și<T>, în cazul special al unei instanțe care implementează interfața ICollection. Deoarece toate tipurile noastre de colecții integrate implementau această interfață, nu a existat niciun câștig de performanță în cele mai comune scenarii. Apropo, <T>metoda de extensie Count() pentru IEnumerable poate face asta de asemenea.

Aceste noi interfețe sunt disponibile pentru . NET 4.5 și . NET for Windows 8。

Note de traducere

[1] Biblioteca clasei de bază, prescurtată BCL. Pentru mai multe informații despre biblioteca clasei de bază, vă rugăm să participați la MSDN.

[2] nomenclatura cămașa călată, cunoscută și sub numele de cămelă minusculă. Formatul este că primul cuvânt începe cu o literă mică; Prima literă a celui de-al doilea cuvânt este scrisă cu majusculă, de exemplu: prenume, numeCognome.

[3] PascalCased, nomenclatura Pascal, cunoscută și sub denumirea de cutie superioară a cămilei. Formatul este că prima literă a fiecărui cuvânt este scrisă cu majusculă, de exemplu: Prenume, NumeNume, CamelCase.




Precedent:Platforma de licențiere software .NET/C# [Cod sursă]
Următor:JS Mining - Cum minează Monero prin web mining?
Disclaimer:
Tot software-ul, materialele de programare sau articolele publicate de Code Farmer Network sunt destinate exclusiv scopurilor de învățare și cercetare; Conținutul de mai sus nu va fi folosit în scopuri comerciale sau ilegale, altfel utilizatorii vor suporta toate consecințele. Informațiile de pe acest site provin de pe Internet, iar disputele privind drepturile de autor nu au legătură cu acest site. Trebuie să ștergi complet conținutul de mai sus de pe calculatorul tău în termen de 24 de ore de la descărcare. Dacă îți place programul, te rugăm să susții software-ul autentic, să cumperi înregistrarea și să primești servicii autentice mai bune. Dacă există vreo încălcare, vă rugăm să ne contactați prin e-mail.

Mail To:help@itsvse.com