HashSet que conserva el orden

Necesito un HashSet que preserve el orden de inserción, ¿hay alguna implementación de esto en el marco?

Standard .NET HashSet no conserva el orden de inserción. Para pruebas simples, el orden de inserción puede conservarse debido a un accidente, pero no está garantizado y no siempre funcionará de esa manera. Para demostrar que es suficiente hacer algunas remociones en el medio.

Consulte esta pregunta para obtener más información al respecto: ¿HashSet conserva el orden de inserción?

He implementado brevemente un HashSet que garantiza el orden de inserción. Utiliza el Dictionary para buscar elementos y LinkedList para conservar el orden. Los tres trabajos de inserción, eliminación y búsqueda aún están en O (1).

 public class OrderedSet : ICollection { private readonly IDictionary> m_Dictionary; private readonly LinkedList m_LinkedList; public OrderedSet() : this(EqualityComparer.Default) { } public OrderedSet(IEqualityComparer comparer) { m_Dictionary = new Dictionary>(comparer); m_LinkedList = new LinkedList(); } public int Count { get { return m_Dictionary.Count; } } public virtual bool IsReadOnly { get { return m_Dictionary.IsReadOnly; } } void ICollection.Add(T item) { Add(item); } public bool Add(T item) { if (m_Dictionary.ContainsKey(item)) return false; LinkedListNode node = m_LinkedList.AddLast(item); m_Dictionary.Add(item, node); return true; } public void Clear() { m_LinkedList.Clear(); m_Dictionary.Clear(); } public bool Remove(T item) { LinkedListNode node; bool found = m_Dictionary.TryGetValue(item, out node); if (!found) return false; m_Dictionary.Remove(item); m_LinkedList.Remove(node); return true; } public IEnumerator GetEnumerator() { return m_LinkedList.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public bool Contains(T item) { return m_Dictionary.ContainsKey(item); } public void CopyTo(T[] array, int arrayIndex) { m_LinkedList.CopyTo(array, arrayIndex); } } 

Puede obtener esta funcionalidad fácilmente usando KeyedCollection especificando el mismo argumento de tipo para TKey y TItem:

 public class OrderedHashSet : KeyedCollection { protected override T GetKeyForItem(T item) { return item; } } 

Si necesita una complejidad constante de Add , Remove , Contains y ordenar preservación, entonces no hay tal colección en .NET Framework 4.5.

Si está de acuerdo con el código de un tercero, eche un vistazo a mi repository (licencia MIT permisiva): https://github.com/OndrejPetrzilka/Rock.Collections

Hay OrderedHashSet :

  • basado en el código fuente HashSet clásico (de .NET Core)
  • conserva el orden de las inserciones y permite el reordenamiento manual
  • características de enumeración invertida
  • tiene las mismas complejidades de operación que HashSet
  • Add operaciones de Add y Remove son un 20% más lentas en comparación con el HashSet
  • consume 8 bytes más de memoria por artículo