Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Muitas vezes, dados semelhantes podem ser tratados de forma mais eficiente quando armazenados e manipulados como uma coleção. Você pode usar a System.Array classe ou as classes nos System.Collectionsnamespaces , System.Collections.Generic, System.Collections.Concurrente System.Collections.Immutable para adicionar, remover e modificar elementos individuais ou um intervalo de elementos em uma coleção.
Existem dois tipos principais de coleções; coleções genéricas e coleções não genéricas. As coleções genéricas são seguras para tipos em tempo de compilação. Por isso, as coleções genéricas normalmente oferecem melhor desempenho. As coleções genéricas aceitam um parâmetro type quando são construídas. Eles não exigem que você transmita de e para o Object tipo quando você adiciona ou remove itens da coleção. Além disso, a maioria das coleções genéricas é suportada em aplicativos da Windows Store. As coleções não genéricas armazenam itens como Object, exigem transmissão e a maioria não tem suporte para o desenvolvimento de aplicativos da Windows Store. No entanto, você pode ver coleções não genéricas em códigos mais antigos.
No .NET Framework 4 e em versões posteriores, as coleções no namespace System.Collections.Concurrent fornecem operações eficientes e thread-safe para acessar itens de coleção a partir de múltiplos threads. As classes de coleção imutáveis no System.Collections.Immutable namespace (pacote NuGet) são inerentemente thread-safe porque as operações são executadas em uma cópia da coleção original e a coleção original não pode ser modificada.
Características comuns da coleção
Todas as coleções fornecem métodos para adicionar, remover ou localizar itens na coleção. Além disso, todas as coleções que direta ou indiretamente implementam a ICollection interface ou a ICollection<T> interface compartilham estes recursos:
A capacidade de enumerar a coleção
As coleções .NET implementam System.Collections.IEnumerable ou System.Collections.Generic.IEnumerable<T> para permitir que a coleção seja iterada. Um enumerador pode ser considerado como um ponteiro móvel para qualquer elemento da coleção. O foreach, em instrução e a Para Cada... Próxima instrução usam o enumerador exposto pelo GetEnumerator método e ocultam a complexidade da manipulação do enumerador. Além disso, qualquer coleção que implementa System.Collections.Generic.IEnumerable<T> é considerada um tipo consultável e pode ser consultada com LINQ. As consultas LINQ fornecem um padrão comum para acessar dados. Eles geralmente são mais concisos e legíveis do que os loops padrão
foreach
e fornecem recursos de filtragem, ordenação e agrupamento. As consultas LINQ também podem melhorar o desempenho. Para obter mais informações, consulte LINQ to Objects (C#),LINQ to Objects (Visual Basic), Parallel LINQ (PLINQ),Introduction to LINQ Queries (C#) e Basic Query Operations (Visual Basic).A capacidade de copiar o conteúdo da coleção para uma matriz
Todas as coleções podem ser copiadas para uma matriz usando o
CopyTo
método. No entanto, a ordem dos elementos na nova matriz é baseada na sequência na qual o enumerador os retorna. A matriz resultante é sempre unidimensional com um limite inferior de zero.
Além disso, muitas classes de coleção contêm os seguintes recursos:
Propriedades de capacidade e contagem
A capacidade de uma coleção é o número de elementos que ela pode conter. A contagem de uma coleção é o número de elementos que ela realmente contém. Algumas coleções ocultam a capacidade ou a contagem ou ambas.
A maioria das coleções expande-se automaticamente em capacidade quando a capacidade atual é atingida. A memória é realocada, e os elementos são copiados da coleção antiga para a nova. Esse design reduz o código necessário para usar a coleção. No entanto, o desempenho da recolha pode ser afetado negativamente. Por exemplo, para List<T>, se Count for menor que Capacity, adicionar um item é uma operação O(1). Se a capacidade precisar ser aumentada para acomodar o novo elemento, adicionar um item se tornará uma operação O(
n
), onden
é Count. A melhor maneira de evitar o mau desempenho causado por várias realocações é definir a capacidade inicial como o tamanho estimado da coleção.A BitArray é um caso especial, a sua capacidade é a mesma que o seu comprimento, que é o mesmo que a sua contagem.
Um limite inferior consistente
O limite inferior de uma coleção é o índice do seu primeiro elemento. Todas as coleções indexadas nos namespaces System.Collections têm um limite inferior de zero, o que significa que são indexadas a partir de 0. Array tem um limite inferior de zero por padrão, mas um limite inferior diferente pode ser definido ao criar uma instância da classe Array usando Array.CreateInstance.
Sincronização para acesso a partir de vários threads (System.Collections somente classes).
Os tipos de coleção não genéricos no namespace System.Collections proporcionam alguma segurança de thread com sincronização, geralmente exposta através dos membros SyncRoot e IsSynchronized. Essas coleções não são thread-safe por padrão. Caso necessite de acesso multi-threaded escalável e eficiente a uma coleção, utilize uma das classes no namespace System.Collections.Concurrent ou considere o uso de uma coleção imutável. Para obter mais informações, consulte Thread-Safe Coleções.
Escolha uma coleção
Em geral, você deve usar coleções genéricas. A tabela a seguir descreve alguns cenários de coleção comuns e as classes de coleção que você pode usar para esses cenários. Se você é novo em coleções genéricas, a tabela a seguir o ajudará a escolher a coleção genérica que funciona melhor para sua tarefa:
Eu quero... | Opções genéricas de recolha | Opções de recolha não genéricas | Opções de coleções seguras para execução simultânea ou imutáveis |
---|---|---|---|
Armazene itens como pares chave/valor para pesquisa rápida por chave | Dictionary<TKey,TValue> | Hashtable (Uma coleção de pares chave/valor que são organizados com base no código hash da chave.) |
ConcurrentDictionary<TKey,TValue> ReadOnlyDictionary<TKey,TValue> ImmutableDictionary<TKey,TValue> |
Aceder a itens por índice | List<T> | Array ArrayList |
ImmutableList<T> ImmutableArray |
Usar itens primeiro a entrar, primeiro a sair (FIFO) | Queue<T> | Queue | ConcurrentQueue<T> ImmutableQueue<T> |
Usar dados Last-In-First-Out (LIFO) | Stack<T> | Stack | ConcurrentStack<T> ImmutableStack<T> |
Acessar itens sequencialmente | LinkedList<T> | Sem recomendação | Sem recomendação |
Receba notificações quando os itens forem removidos ou adicionados à coleção. (implementa INotifyPropertyChanged e INotifyCollectionChanged) | ObservableCollection<T> | Sem recomendação | Sem recomendação |
Uma coleção ordenada | SortedList<TKey,TValue> | SortedList | ImmutableSortedDictionary<TKey,TValue> ImmutableSortedSet<T> |
Um conjunto para funções matemáticas | HashSet<T> SortedSet<T> |
Sem recomendação | ImmutableHashSet<T> ImmutableSortedSet<T> |
Complexidade algorítmica de coleções
Ao escolher uma classe de coleção, vale a pena considerar possíveis compensações no desempenho. Use a tabela a seguir para fazer referência a como vários tipos de coleção mutáveis se comparam em complexidade algorítmica com suas contrapartes imutáveis correspondentes. Muitas vezes, os tipos de coleção imutáveis têm um desempenho menor, mas proporcionam imutabilidade - o que muitas vezes é um benefício comparativo válido.
Mutável | Amortizado | Pior caso | Imutável | Complexidade |
---|---|---|---|---|
Stack<T>.Push |
O(1) | O(n ) |
ImmutableStack<T>.Push |
O(1) |
Queue<T>.Enqueue |
O(1) | O(n ) |
ImmutableQueue<T>.Enqueue |
O(1) |
List<T>.Add |
O(1) | O(n ) |
ImmutableList<T>.Add |
O(log n ) |
List<T>.Item[Int32] |
O(1) | O(1) | ImmutableList<T>.Item[Int32] |
O(log n ) |
List<T>.Enumerator |
O(n ) |
O(n ) |
ImmutableList<T>.Enumerator |
O(n ) |
HashSet<T>.Add , consulta |
O(1) | O(n ) |
ImmutableHashSet<T>.Add |
O(log n ) |
SortedSet<T>.Add |
O(log n ) |
O(n ) |
ImmutableSortedSet<T>.Add |
O(log n ) |
Dictionary<T>.Add |
O(1) | O(n ) |
ImmutableDictionary<T>.Add |
O(log n ) |
Dictionary<T> consulta |
O(1) | O(1) – ou estritamente O(n ) |
ImmutableDictionary<T> consulta |
O(log n ) |
SortedDictionary<T>.Add |
O(log n ) |
O(n log n ) |
ImmutableSortedDictionary<T>.Add |
O(log n ) |
A List<T>
pode ser enumerado eficientemente usando um for
loop ou um foreach
loop. Um ImmutableList<T>
, no entanto, funciona mal dentro de um ciclo for
, devido ao tempo O(log n
) para o seu indexador. Enumerar um ImmutableList<T>
usando um foreach
loop é eficiente porque ImmutableList<T>
usa uma árvore binária para armazenar seus dados em vez de uma matriz como List<T>
usa. Uma matriz pode ser rapidamente indexada, enquanto uma árvore binária deve ser descida até que o nó com o índice desejado seja encontrado.
Além disso, SortedSet<T>
tem a mesma complexidade que ImmutableSortedSet<T>
porque ambos usam árvores binárias. A diferença significativa é que ImmutableSortedSet<T>
usa uma árvore binária imutável. Como ImmutableSortedSet<T>
também oferece uma System.Collections.Immutable.ImmutableSortedSet<T>.Builder classe que permite mutação, você pode ter imutabilidade e desempenho.
Artigos relacionados
Título | Descrição |
---|---|
Selecionando uma classe de coleção | Descreve as diferentes coleções e ajuda a selecionar uma para o seu cenário. |
Tipos de coleção comumente usados | Descreve tipos de coleção genéricos e não genéricos comumente usados, como System.Array, System.Collections.Generic.List<T>e System.Collections.Generic.Dictionary<TKey,TValue>. |
Quando usar coleções genéricas | Discute o uso de tipos de coleção genéricos. |
Comparações e classificações dentro de coleções | Discute o uso de comparações de igualdade e comparações de classificação em coleções. |
Tipos de coleção ordenados | Descreve o desempenho e as características das coleções classificadas. |
Tipos de coleção Hashtable e Dictionary | Descreve as características de tipos de dicionário baseados em hash, tanto genéricos como não genéricos. |
Thread-Safe Coleções | Descreve tipos de coleção como System.Collections.Concurrent.BlockingCollection<T> e System.Collections.Concurrent.ConcurrentBag<T> que suportam acesso simultâneo seguro e eficiente de vários threads. |
System.Collections.Immutable | Apresenta as coleções imutáveis e fornece links para os tipos de coleção. |