Il presente articolo è stato tradotto automaticamente.

Il programmatore al lavoro

Raccolte .NET: introduzione a C5

Ted Neward

 

Ted NewardHo una confessione da fare.

Di giorno, io lavoro come sviluppatore .NET mite per Neudesic LLC, una società di consulenza. Ma di notte, dopo che la moglie e i miei figli si sono addormentati, sgattaiolare fuori di casa, portatile in mano e viaggio al mio nascondiglio segreto (un Denny su 148th) e... Scrivere codice Java.

Sì, la gente, io vivo una doppia vita come un Java e uno sviluppatore .NET — o, più precisamente, una Java Virtual Machine (JVM) — sviluppatore. Uno dei vantaggi di vivere una doppia stile di vita interessanti è che riesco a vedere aree dove il Microsoft .NET Framework ha alcune grandi idee che possono essere ricondotti a JVM. Una tale idea è stata quella di attributi personalizzati, che la JVM adottato in Java5 (nel 2005 o giù di lì) con il nome "annotazioni". Ma è vero anche il contrario: La JVM, infatti, ottenere poche cose giuste che il CLR e .NET Base Class Library (BCL) non ha (o almeno non ha ottenuto abbastanza come diritto, se ti senti un po ' difensiva). Una di queste zone si trova nel cuore della BCL .NET: raccolte.

Collezioni: Una critica

Parte del difetto nelle collezioni .NET sta nel fatto che il team BCL dovuto scrivere cose stupide due volte: volta per il rilascio di .NET Framework 1.0/1.1, prima di farmaci generici erano disponibili e di nuovo per il .NET Framework 2.0, dopo i generics sono stati parte di CLR, perché le collezioni senza versioni fortemente tipizzate sono solo tipo di sciocche. Questo significava automaticamente che uno di questi è stato associato a essere lasciati a marcire, essenzialmente, a favore di qualunque miglioramenti o aggiunte alla libreria dovevano venire avanti. (Java abbassato questo particolare problema sostituendo essenzialmente"" le versioni non-genericizzati con versioni di origine, che fu possibile solo a causa del modo Java ha fatto generics — che non è qualcosa che ho intenzione di entrare.) E, a parte i miglioramenti che sono venuto via LINQ in Visual Studio 2008 e c# 3.0, le collezioni libreria mai realmente avuto tanto amore dopo il rilascio della versione 2.0, che a sua volta più o meno appena re-AP­vigore lo System. Collections classi in un nuovo spazio dei nomi (System.Collections.Generic o SCG) di fortemente tipizzato versioni.

Ancora più importante, però, il design delle collezioni .NET sembra sono stati più concentrati su ottenere qualcosa di pratico e utile out into the wild come parte della 1.0 release, piuttosto che cercare di pensare profondamente il design delle collezioni e come potrebbe essere esteso. Questa era una zona in cui il Framework .NET davvero (sospetto involontariamente) parallelo al mondo Java. Quando Java 1.0 spediti, includeva una serie di collezioni basic, utilitaristiche. Ma aveva alcuni difetti di progettazione (i più eclatanti di cui era la decisione che aveva lo Stack di classe, una collezione di last-in-first-out, direttamente estende la classe Vector, che era fondamentalmente un ArrayList). Dopo Java 1.1 spedito, alcuni ingegneri di Sun Microsystems ha lavorato duramente per riscrivere le classi di insiemi, che divenne noto come le collezioni Java — e spedito come una parte di Java 1.2.

In ogni caso, il Framework .NET è arretrato per un rinnovamento delle sue classi di insiemi, idealmente in un modo che è almeno per lo più compatibile con l'esistente SCG classi. Fortunatamente, i ricercatori presso l'IT Università di Copenhagen in Danimarca hanno prodotto un degno successore e complemento alle classi SCG: una libreria che chiamano le classi Collection completa di Copenaghen per c# o C5 in breve.

Logistica C5

Per iniziare, C5 è trovato sul Web a itu.dk/research/c5 se volete vedere la cronologia oppure ottenere un link a un libro (PDF) su C5, anche se il libro è qualche release vecchie. O, in alternativa, è disponibile attraverso NuGet attraverso C5 il (da-ormai onnipresente) comando Install Package, semplicemente digitando "Install pacchetto C5." Si noti che il C5 è scritto per essere disponibile per Visual Studio sia Mono, e quando NuGet installa il pacchetto, aggiungerà i riferimenti all'assembly C5.dll così come l'Assemblea C5Mono.dll. Queste sono ridondanti a vicenda, così uno che non si desidera eliminare. Per esplorare C5 raccolte attraverso una serie di test di esplorazione, ho creato un progetto Visual c# Test e ha aggiunto C5 a tale progetto. Oltre a ciò, il solo notevole cambiamento al codice è due istruzioni "utilizzando", che presuppone anche la documentazione di C5:

using SCG = System.Collections.Generic;
using C5;

Il motivo per cui l'alias è semplice: C5 "reimplementa" poche interfacce e classi che sono lo stesso nella versione SCG, denominate così alias la roba vecchia lascia disponibile a noi, ma sotto un breve prefisso (IList <T> è la versione C5, ad esempio, considerando che SCG.IList <T> è la versione "classica" da SCG).

A proposito, nel caso in cui gli avvocati chiedono, C5 è aperto di provenienza sotto licenza MIT, quindi sei molto più in grado di modificare o migliorare alcune delle classi C5 che si sarebbe sotto una GNU General Public License (GPL) o GNU Lesser General Public License (LGPL).

C5 Design panoramica

Guardando l'approccio progettuale di C5, sembra simile allo stile SCG, in quanto raccolte sono suddivisi in due "livelli": uno strato di interfaccia che descrive l'interfaccia e il comportamento previsto di un determinato insieme e un livello di implementazione che fornisce il codice effettivo supporto per le interfacce di uno o più desiderate. Le classi SCG approccio questa idea, ma in alcuni casi non seguono su di esso particolarmente bene — ad esempio, non abbiamo alcuna flessibilità in termini di implementazione di SortedSet <T> (significato, la scelta di basata su array, legato-elenco-based o hash-based, ognuno dei quali ha caratteristiche diverse per quanto riguarda le prestazioni di inserimento, l'attraversamento e così via). In alcuni casi il SCG classi semplicemente mancano alcuni tipi di raccolta — una circolare in coda, ad esempio (in cui, quando l'ultimo elemento nella coda è traslato, l'iterazione "avvolge" verso la parte anteriore della coda ancora), o una semplice raccolta di "borsa" (che non offre alcuna funzionalità tranne to contengono elementi, così evitando inutili overhead dell'ordinamento, l'indicizzazione e così via).

Concesso, lo sviluppatore .NET media, questo non sembra molto di una perdita. Ma in molte applicazioni, come prestazioni cominciano a diventare un tema centrale, scegliendo la classe insieme giusto per abbinare il problema a portata di mano diventa più critico. Questa è una raccolta che sarà stabilita una volta e ha attraversata frequentemente? O si tratta di una raccolta che sarà aggiunto o rimosso frequentemente ma raramente attraversata? Se questa collezione è il cuore di una funzione di applicazione (o la stessa applicazione), la differenza tra questi due potrebbe significare la differenza tra "Wow, questo app urla!" e "bene, gli utenti è piaciuto, ma solo pensavano che fosse troppo lento."

C5, allora, vale come uno dei suoi principi fondamentali che gli sviluppatori dovrebbero "codice per le interfacce, non le implementazioni," e, come tale, offre più di una dozzina di diverse interfacce che descrivono ciò che deve fornire l'insieme sottostante. ICollection <T> è la base di esso tutto, garantendo il comportamento collezione basic, ma da lì troviamo IList <T>, Iindicizzata <T>, ISorted <T> e ISequenced <T>, solo per iniziare. Ecco l'elenco completo delle interfacce, le loro relazioni ad altre interfacce e le loro garanzie globale:

  • Un SCG.IEnumerable <T> possono avere i relativi elementi enumerati. Tutte le collezioni e i dizionari sono enumerabili.
  • Un IDirectedEnumerable <T> è enumerabile che può essere invertito, dando un indietro enumerabile che enumera gli elementi nell'ordine opposto.
  • Un ICollectionValue <T> è un valore di raccolta. Non supporta la modifica, è enumerabile, sa quanti elementi ha e copiarli in una matrice.
  • Un IDirectedCollectionValue <T> è un valore di insieme che può essere invertito in un valore di raccolta con le versioni precedenti.
  • Un IExtensible <T> è un insieme in cui gli elementi possono essere aggiunti.
  • Un IPriorityQueue <T> è un estensibile cui meno e gli elementi più grandi possono essere trovato (e rimosso) in modo efficiente.
  • Interfaccia ICollection <T> è un estensibile da quali elementi può anche essere rimosso.
  • Un ISequenced <T> è un insieme in cui gli elementi vengono visualizzati in una sequenza particolare (determinata mediante ordine di inserimento o elemento di ordinamento).
  • Un Iindicizzata <T> è una raccolta sequenziata cui gli elementi sono accessibili tramite indice.
  • Un ISorted <T> è una collezione sequenziata in cui gli elementi vengono visualizzati in crescente ordine; elemento confronti determinano la sequenza di elementi. Può trovare in modo efficiente il predecessore o successore (nell'insieme) di un determinato elemento.
  • Un IIndexedSorted <T> è una raccolta ordinata e indicizzata. Esso può determinare efficientemente quanti elementi sono maggiori o uguali a un determinato elemento x.
  • Un IPersistentSorted <T> è un insieme ordinato di cui uno può fare in modo efficiente un'istantanea — che è, una copia in sola lettura che rimarrà inalterata da aggiornamenti alla raccolta originale.
  • Un IQueue <T> è una coda di first-in-first-out (FIFO) che inoltre supporta l'indicizzazione.
  • Un IStack <T> è una pila di last-in-first-out (LIFO).
  • Un IList <T> è una raccolta indicizzata e pertanto sequenziata, dove elemento ordine è determinato da inserimenti ed eliminazioni. Esso deriva dalla SCG.IList <T>.

In termini di implementazioni, C5 ha abbastanza pochi, tra cui code circolari; matrice-backed nonché elenchi collegati-elenco-backed, ma anche liste hash-array e liste concatenate su hashed; matrici avvolti; matrici ordinate; insiemi basati sull'albero e sacchetti; e di più.

C5 Stile di codifica

Fortunatamente, C5 non richiede un cambiamento significativo nella codifica stile — e, ancor meglio, supporta tutte le operazioni di LINQ (perché esso si basa sulla cima delle interfacce SCG, di cui i metodi di estensione LINQ chiave off), così in alcuni casi si può cadere in un insieme di C5 in costruzione il tempo senza modificare il codice intorno ad esso. Vedi Figura 1 per un esempio di questo.

Figura 1 Guida introduttiva con C5

// These are C5 IList and ArrayList, not SCG
IList<String> names = new ArrayList<String>();
names.AddAll(new String[] { "Hoover", "Roosevelt", "Truman",
  "Eisenhower", "Kennedy" });
// Print list:
Assert.AreEqual("[ 0:Hoover, 1:Roosevelt, 2:Truman, 3:Eisenhower," +
  " 4:Kennedy ]", names.ToString());
// Print item 1 ("Roosevelt") in the list
Assert.AreEqual("Roosevelt", names[1]);
Console.WriteLine(names[1]);
// Create a list view comprising post-WW2 presidents
IList<String> postWWII = names.View(2, 3);
// Print item 2 ("Kennedy") in the view
Assert.AreEqual("Kennedy", postWWII[2]);
// Enumerate and print the list view in reverse chronological order
Assert.AreEqual("{ Kennedy, Eisenhower, Truman }",
  postWWII.Backwards().ToString());

Anche senza aver mai guardato la documentazione C5, è abbastanza facile da capire che cosa sta accadendo in questi esempi.

C5 vs. SCG collezione implementazioni

Questa è solo la punta dell'iceberg rispetto alla C5. Nel mio prossimo articolo potrai guardare alcuni esempi pratici dell'utilizzo di C5 invece le implementazioni di raccolta SCG — e alcuni dei benefici che facendo così ci dà. Vi incoraggio a non aspettare, però: La cosa di NuGet, abbattere C5 e iniziare ad esplorare per conto proprio — c'è un sacco lì per farvi divertire voi stessi nel frattempo.

Codificazione felice!

Ted Neward è un consulente architettonico con Neudesic LLC. Ha scritto oltre 100 articoli ed è un autore e coautore di una dozzina di libri, tra cui "Professional F # 2.0" (Wrox, 2010). Egli è un F # MVP e noto esperto di Java e parla a sia Java e .NET conferenze in giro per il mondo. Egli consulta e mentors regolarmente — è possibile contattarlo al ted@tedneward.com o Ted.Neward@neudesic.com se siete interessati ad avere lui venire a lavorare con il vostro team. Ha Blog at blogs.tedneward.com e possono essere seguiti su Twitter a twitter.com/tedneward.

Grazie all'esperto tecnica seguente per la revisione di questo articolo: Immo Landwerth