Quando usare raccolte generiche
L'utilizzo di raccolte generiche offre il vantaggio automatico dell'indipendenza dai tipi senza la necessità di derivare da un tipo di raccolta di base e implementare membri specifici di tipo. I tipi di raccolte generiche offrono anche prestazioni migliori rispetto ai tipi di raccolte non generiche corrispondenti (e tipi derivati dai tipi di raccolte di base non generiche) quando gli elementi della raccolta sono tipi di valore, perché con i generics non è necessario il boxing degli elementi.
Per programmi destinati a .NET Standard 1.0 o versione successiva, è necessario usare le classi di raccolte generiche nello spazio dei nomi System.Collections.Concurrent quando più thread potrebbero aggiungere o rimuovere elementi dalla raccolta contemporaneamente. Inoltre, quando si desidera l'immutabilità, prendere in considerazione le classi di raccolta generiche nello spazio dei nomi System.Collections.Immutable.
I seguenti tipi generici corrispondono ai tipi di raccolte esistenti:
Dictionary<TKey,TValue> e ConcurrentDictionary<TKey,TValue> sono le classi generiche che corrispondono a Hashtable.
Collection<T> è la classe generica che corrisponde a CollectionBase. Collection<T> può essere usata come classe di base, ma a differenza di CollectionBase, non è astratta, quindi è molto più semplice da usare.
ReadOnlyCollection<T> è la classe generica che corrisponde a ReadOnlyCollectionBase. ReadOnlyCollection<T> non è astratta e ha un costruttore che semplifica l'esposizione di una classe List<T> esistente come raccolta di sola lettura.
Le classi generiche Queue<T>, ConcurrentQueue<T>, ImmutableQueue<T>, ImmutableArray<T>, SortedList<TKey,TValue> e ImmutableSortedSet<T> corrispondono alle rispettive classi non generiche con gli stessi nomi.
Tipi aggiuntivi
Diversi tipi di raccolte generiche non hanno controparti non generiche. tra cui:
LinkedList<T> è un elenco collegato di uso generale che fornisce le operazioni di inserimento e rimozione O(1).
SortedDictionary<TKey,TValue> è un dizionario ordinato con operazioni di inserimento e recupero O(log
n
), che lo rende un'utile alternativa a SortedList<TKey,TValue>.KeyedCollection<TKey,TItem> è un ibrido tra un elenco e un dizionario, che fornisce un metodo per memorizzare oggetti contenenti le loro stesse chiavi.
BlockingCollection<T> implementa una classe di raccolta con funzionalità di delimitazione e blocco.
ConcurrentBag<T> permette di eseguire rapidamente le operazioni di inserimento e rimozione di elementi non ordinati.
Generatori non modificabili
Quando si desidera la funzionalità di immutabilità nell'app, lo spazio dei nomi System.Collections.Immutable offre tipi di raccolta generici da poter usare. Tutti i tipi di raccolta non modificabili offrono le classi Builder
, che possono ottimizzare le prestazioni quando si eseguono più mutazioni. La classe Builder
esegue il batch delle operazioni in uno stato modificabile. Al termine di tutte le mutazioni, chiamare il metodo ToImmutable
per bloccare tutti i nodi e creare una raccolta generica non modificabile, ad esempio un oggetto ImmutableList<T>.
L'oggetto Builder
può essere creato chiamando il metodo non generico CreateBuilder()
. Da un'istanza Builder
, è possibile chiamare ToImmutable()
. Analogamente, dalla raccolta Immutable*
, è possibile chiamare ToBuilder()
per creare un'istanza del generatore dalla raccolta generica non modificabile. Seguono i vari tipi Builder
.
- ImmutableArray<T>.Builder
- ImmutableDictionary<TKey,TValue>.Builder
- ImmutableHashSet<T>.Builder
- ImmutableList<T>.Builder
- ImmutableSortedDictionary<TKey,TValue>.Builder
- ImmutableSortedSet<T>.Builder
LINQ to Objects
La funzionalità LINQ to Objects consente di usare le query LINQ per accedere agli oggetti in memoria purché il tipo dell'oggetto implementi l'interfaccia System.Collections.IEnumerable o System.Collections.Generic.IEnumerable<T> . Le query LINQ forniscono un modello comune per l'accesso ai dati, sono in genere più concise e leggibili dei cicli foreach
standard e forniscono funzionalità di filtro, ordinamento e raggruppamento. Le query LINQ possono inoltre migliorare le prestazioni. Per altre informazioni, vedere LINQ to Objects (C#), LINQ to Objects (Visual Basic) e Parallel LINQ (PLINQ).
Funzionalità aggiuntive
Alcuni tipi generici hanno funzionalità che non si trovano nei tipi di raccolte non generiche. Ad esempio, la classe List<T> , che corrisponde alla classe ArrayList non generica, ha una serie di metodi che accettano i delegati generici, come ad esempio il delegato Predicate<T> che consente di specificare metodi per la ricerca nell'elenco, il delegato Action<T> che rappresenta metodi che agiscono su ciascun elemento dell'elenco e il delegato Converter<TInput,TOutput> che consente di definire le conversioni tra tipi.
La classe List<T> consente di specificare le proprie implementazioni di interfaccia IComparer<T> generica per l'ordinamento e la ricerca nell'elenco. Anche le classi SortedDictionary<TKey,TValue> e SortedList<TKey,TValue> hanno la stessa capacità. Inoltre, queste classi consentono di specificare gli operatori di confronto quando viene creata la raccolta. In modo analogo, le classi Dictionary<TKey,TValue> e KeyedCollection<TKey,TItem> consentono di specificare operatori di confronto di uguaglianza personalizzati.