Pergunta

Será que o href="https://msdn.microsoft.com/en-us/library/bb359438(v=vs.110).aspx" rel="noreferrer"> HashSet coleção introduzido em .NET 3,5 preservar a ordem de inserção quando iterado usando foreach?

O documentação estados, que a coleção não é ordenada, mas ele não diz nada sobre a ordem de inserção. Um pré-lançamento BCL entrada de blog estados que é desordenado, mas estados este artigo que ele é projetado para preservar a inserção ordem. Meu testes limitados sugere, que a ordem é preservada, mas que poderia ser uma coincidência.

Foi útil?

Solução

Este HashSet MSDN página especificamente diz:

Um conjunto é uma coleção que não contém elementos duplicados, e cujos elementos estão em nenhuma ordem particular.

Outras dicas

Eu acho que o artigo alegando que preserva ordenação é apenas errado liso. Para testes simples a ordem de inserção pode muito bem ser preservada devido à estrutura interna, mas não é garantido e nem sempre funciona dessa forma. Vou tentar chegar a um contra-exemplo.

EDIT: Aqui está o contra-exemplo:

using System;
using System.Collections.Generic;

class Test
{
    static void Main()
    {
        var set = new HashSet<int>();

        set.Add(1);
        set.Add(2);
        set.Add(3);
        set.Remove(2);
        set.Add(4);


        foreach (int x in set)
        {
            Console.WriteLine(x);
        }
    }
}

Este gravuras 1, 4, 3 3, apesar de ter sido inserido antes de 4.

de possível que, se você nunca remover quaisquer itens, ele irá preservar a ordem de inserção. Eu não tenho certeza, mas eu não seria totalmente surpreso. No entanto, eu acho que seria uma idéia muito ruim que confiar em que:

  • Não está documentada a trabalhar dessa maneira, e a documentação afirma explicitamente que não é classificada.
  • Eu não olhei para as estruturas internas ou código fonte (que eu não tenho, obviamente) -. Eu teria que estudá-las cuidadosamente antes de fazer qualquer reclamação de uma forma firme
  • A implementação poderia muito facilmente mudar entre as versões do quadro. Baseando-se isso seria como contando com a implementação string.GetHashCode não mudar - o que algumas pessoas fizeram voltar no .NET 1.1 dias, e então eles se queimou quando a implementação fez mudança no .NET 2.0 ...

Os estados de documentação:

Um HashSet <(Of <(T>)>) coleção não está classificada e não pode conter elementos duplicados. Se a ordem ou elemento de duplicação é mais importante do que o desempenho para o seu aplicativo, considere usar o List <(Of <(T>)>) classe juntamente com o método Sort.

Por isso, não importa se ele realmente preserva a ordem dos elementos na implementação atual, pois não está documentada como fazê-lo, e mesmo que parece agora isso pode mudar a qualquer momento no futuro (mesmo em um hotfix para o quadro).

Você deve estar programando contra contratos documentados , não detalhes da implementação .

Não é especificamente uma href="http://msdn.microsoft.com/en-us/library/dd412070.aspx" rel="nofollow"> coleção SortedSet<T> em .NET4 .

Isto lhe daria a classificação, mas pouco provável que seja a classificação do pedido de veiculação. Desde que você pode usar um IComparer personalizado que você poderia, teoricamente, fazer este fazer nada.

Não, um conjunto de hash não vai preservar a ordem de inserção, pelo menos não de maneira previsível. Você poderia usar um LinkedHashSet (Java), ou um equivalente. A LinkedHashSet vai preservar a ordem.

Se você deseja ordem, você não deve mesmo estar usando um conjunto em primeiro lugar ... não é feita para elementos ordenados, exceto em casos excepcionais.

EDIT: Parece que eu estou pregando: -. / Desculpe

A leitura do código fonte para HashSet.AddIfNotPresent você pode ver ordem de inserção é preservada assumindo não houve quaisquer exclusões .

ordem conservas Assim new HashSet<string> { "Tom", "Dick", "Harry" }, mas se você, em seguida, remover Dick e adicionar Rick, a ordem será [ "Tom", "Rick", "Harry"].

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top