Questo articolo è un articolo speculare di traduzione automatica, clicca qui per saltare all'articolo originale.

Vista: 19672|Risposta: 1

[Fonte] . .NET La storia dell'interfaccia di raccolta in sola lettura

[Copiato link]
Pubblicato su 05/02/2018 14:28:10 | | |
.NET 4.5Sono state aggiunte due nuove interfacce di raccolta, IReadOnlyList e IReadOnlyDictionary. Anche se queste interfacce possono sembrare così banali in superficie, rivelano storie piuttosto complesse su compatibilità retroattiva, interoperabilità e il ruolo della co-mutabilità.

IReadOnlyList e IReadOnlyDictionary sono due interfacce che gli sviluppatori .NET hanno sempre desiderato avere. Oltre a fornire un certo senso di simmetria (a differenza delle interfacce scrivibili), un'interfaccia di sola lettura dovrebbe eliminare l'implementazione di metodi che lanciano solo un'eccezione NotSupportedException senza fare nulla. Tutto ciò non fu completato a causa di vincoli di tempo.

La prossima opportunità è arrivata. NET 2.0. Questo permette a Microsoft di ritirare le collezioni con tipe debole e sostituirle con collezioni peer fortemente tipate. Tuttavia, il team della biblioteca base[1] perse ancora una volta l'opportunità di fornire una lista di sola lettura, come scrisse Kit George,

Poiché intendiamo fornire un'implementazione predefinita per il problema di cui parli con Joe, invece di fornire un'interfaccia, forniamo la classe base ReadOnlyCollectionBase. Tuttavia, capisco perché le persone siano riluttanti a usarlo perché non è un tipo forte. Ma con l'introduzione dei generici, ora abbiamo anche <T>ReadOnlyCollection, così non solo ottieni la stessa funzionalità, ma anche un tipo forte: fantastico!

Poiché <T>ReadOnlyCollection non è una classe sigillata, puoi scrivere la tua collezione a velocità piena se necessario. Poiché queste collezioni che abbiamo creato per questo sono adattabili a esigenze generali, non intendiamo introdurre interfacce per lo stesso concetto.

Krzysztof Cwalina espresse anch'egli la sua opinione su questo argomento,

Che questo possa sorprendere o meno, IList e IList <T>sono le due interfacce che intendiamo utilizzare per le collezioni di sola lettura. Entrambi hanno la proprietà boolean IsReadOnly, che dovrebbe restituire vera quando una collezione di sola lettura implementa questa proprietà. Il motivo per cui non vogliamo aggiungere un'interfaccia di sola lettura pura è che riteniamo che aggiunga troppa complessità inutile alla libreria base. Si noti che, in termini di complessità, ci riferiamo sia a questa nuova interfaccia sia ai suoi consumatori.

Crediamo che se il progettista dell'API non si preoccupa di controllare la proprietà IsReadOnly a runtime e le eccezioni che potrebbe generare, allora in questo caso sia accettabile usare l'interfaccia IList; Se sono disposti a fornire un'API personalizzata davvero pulita in una sola volta, allora in questo caso dovrebbero mostrare l'implementazione dell'interfaccia IList e pubblicare un'API di sola lettura su misura. Quest'ultimo è tipico delle collezioni esposte dal modello dell'oggetto.

Anche se gli sviluppatori si sono lamentati di questa situazione, le nuove opportunità offerte dai generici superano di gran lunga questo punto cruciale e il problema è in . NET 4 era stato in gran parte ignorato in passato. Tuttavia, questa decisione ha anche suscitato alcune reazioni, di cui parleremo più avanti.

Con l'ingresso. Una nuova e entusiasmante funzionalità in .NET 4 è stata aggiunta all'esecuzione. In una versione precedente. .NET, quando le interfacce diventano tipi, queste sono eccessivamente limitate. Ad esempio, anche se il Cliente eredita da Persona, non è possibile passare un oggetto di tipo IEnumerable <Customer>come parametro a una funzione di tipo IEnumerable<Person>. Con l'aggiunta del supporto covariante, questa restrizione è stata parzialmente rimossa.

Diciamo "parzialmente" perché in alcuni casi le persone dovrebbero usare un'interfaccia con un'API ricca tutta insieme, invece di usare un'interfaccia IEnumerable. Anche se l'interfaccia IList non è covariante, dovrebbe esserlo un'interfaccia di lista di sola lettura. Purtroppo, . Il team della libreria base .NET ha nuovamente deciso di non affrontare questa svista.

Poi l'introduzione di WinRT e il ritorno di COM hanno cambiato tutto. L'interoperabilità COM era una tecnologia che gli sviluppatori usavano quando non avevano altra scelta, ma è diventata un . La pietra angolare della programmazione .NET. E poiché WinRT espone le <T>interfacce IVectorView e IMapView<K, V> quindi. .NET deve anche essere adattato di conseguenza.

Una caratteristica interessante del programma WinRT è l'annuncio di API diverse ma simili per ogni piattaforma di sviluppo. Come forse già saprai, tutti i nomi dei metodi sono rappresentati da camelCased [2], mentre gli sviluppatori di C++ e .NET vedono i nomi dei metodi come PascalCased [3]. Un altro cambiamento più drastico è la mappatura automatica tra le interfacce C++ e .NET. Quindi. Gli sviluppatori .NET non devono occuparsi dello spazio nominale Windows.Foundation.Collections, basta continuare a usare lo spazio System.Collections.Generic. Le interfacce IVectorView <T>e IMapView<K, V> saranno convertite dal runtime in <T>interfacce IReadOnlyList e IReadOnlyDictionary<TKey, TValue>, rispettivamente.

Vale la pena notare che questi nomi di interfaccia in C++/WinRT sono in una certa misura più accurati. Queste interfacce sono usate per rappresentare alcune viste di una collezione, ma l'interfaccia non garantisce che la collezione stessa sia immutabile. Anche tra chi ha esperienza. Un errore comune tra gli sviluppatori .NET è presumere che il tipo ReadOnlyCollection sia una copia di una collezione immutabile, ma in realtà è solo un wrapper per una collezione attiva (vedi il post omonimo di Andrew Arnott per maggiori informazioni su collezioni di sola lettura, congelate e immutabili).

Sebbene l'interfaccia IList <T>abbia tutti gli stessi membri dell'interfaccia IReadOnlyList <T>e tutte <T>le liste di tipo IList possano essere rappresentate come liste di sola lettura, IList <T>non eredita da IReadOnlyList<T>, cosa che potrebbe essere interessante da conoscere. Spiegò Immo Landwerth,

Il motivo per cui funziona è che quelle interfacce di sola lettura sono puri sottoinsiemi delle interfacce di lettura-scrittura, il che sembra un'ipotesi ragionevole. Purtroppo, questa assunzione non corrisponde alla realtà, poiché ogni metodo su ogni interfaccia a livello di metadati ha il proprio slot (il che rende efficaci implementazioni esplicite di interfaccia).

O in altre parole, l'unica possibilità di introdurre un'interfaccia di sola lettura come una classe base di classe variabile è tornare a . NET 2.0, cioè quando sono stati originariamente concepiti. Una volta completamente implementato, l'unica modifica che può apportare è aggiungere marker covarianti e/o inverter (rappresentati come "in" e "out" in VB e C#).

Quando mi è stato chiesto perché non esista <T>un'interfaccia IReadOnlyCollection, Immo ha risposto,

Abbiamo considerato questo design, ma abbiamo ritenuto che aggiungere un tipo che fornisse solo l'attributo Count non avrebbe aggiunto molto valore alla libreria base. Nel team della libreria base, crediamo che se un'API parte da meno 1000, allora anche fornire un certo valore non sia sufficiente a giustificare l'aggiunta. La motivazione per l'aggiunta di nuove API include anche un costo, ad esempio, gli sviluppatori avranno più concetti tra cui scegliere. All'inizio pensavamo che aggiungere questo tipo avrebbe fatto funzionare meglio il codice in certi scenari in cui si vuole solo ottenere un conteggio e poi fare qualcosa di interessante con esso. Ad esempio, aggiungere in massa a una collezione esistente. Tuttavia, in questi scenari, abbiamo incoraggiato le persone a usare solo <T>l'interfaccia IEnumerable, e <T>nel caso speciale di avere un'istanza che implementa l'interfaccia ICollection. Poiché tutti i nostri tipi di collezione integrati hanno implementato questa interfaccia, non c'è stato alcun aumento di prestazioni in quegli scenari più comuni. A proposito, <T>anche il metodo di estensione Count() per IEnumerable può fare questo.

Queste nuove interfacce sono disponibili per . NET 4.5 e . NET for Windows 8。

Note sulla traduzione

[1] Biblioteca di Classe Base, abbreviata in BCL. Per maggiori informazioni sulla biblioteca della classe base, partecipa a MSDN.

[2] cammelCased, nomenclatura a gobba, nota anche come cassa in cammello inferiore. Il formato prevede che la prima parola inizi con una lettera minuscola; La prima lettera della seconda parola è maiuscola, ad esempio: nome, cognome.

[3] PascalCased, nomenclatura Pascal, nota anche come cassa superiore del cammello. Il formato prevede che la prima lettera di ogni parola sia maiuscola, ad esempio: Nome, Cognome, CasoCasa.




Precedente:Piattaforma di Licenze Software .NET/C# [Codice sorgente]
Prossimo:JS Mining - Come estrae Monero con il web mining?
Disconoscimento:
Tutto il software, i materiali di programmazione o gli articoli pubblicati dalla Code Farmer Network sono destinati esclusivamente all'apprendimento e alla ricerca; I contenuti sopra elencati non devono essere utilizzati per scopi commerciali o illegali, altrimenti gli utenti dovranno sostenere tutte le conseguenze. Le informazioni su questo sito provengono da Internet, e le controversie sul copyright non hanno nulla a che fare con questo sito. Devi eliminare completamente i contenuti sopra elencati dal tuo computer entro 24 ore dal download. Se ti piace il programma, ti preghiamo di supportare software autentico, acquistare la registrazione e ottenere servizi autentici migliori. In caso di violazione, vi preghiamo di contattarci via email.

Mail To:help@itsvse.com