namespace UIWidgets { using System; using System.Collections; using System.Collections.Generic; /// /// Linked HashSet. /// /// Type of item. public sealed class LinkedHashSet : ICollection { readonly LinkedList list; readonly Dictionary> dict; /// /// Initializes a new instance of the class. /// public LinkedHashSet() { list = new LinkedList(); dict = new Dictionary>(); } /// /// Initializes a new instance of the class. /// /// Source. [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "HAA0401:Possible allocation of reference type enumerator", Justification = "Required.")] public LinkedHashSet(IEnumerable source) { list = new LinkedList(); dict = new Dictionary>(); foreach (var item in source) { Add(item); } } /// /// Initializes a new instance of the class. /// /// Source. public LinkedHashSet(T[] source) { list = new LinkedList(); dict = new Dictionary>(); foreach (var item in source) { Add(item); } } /// /// Initializes a new instance of the class. /// /// Source. public LinkedHashSet(List source) { list = new LinkedList(); dict = new Dictionary>(); foreach (var item in source) { Add(item); } } /// /// Initializes a new instance of the class. /// /// Source. public LinkedHashSet(ObservableList source) { list = new LinkedList(); dict = new Dictionary>(); foreach (var item in source) { Add(item); } } /// /// Get items. /// /// Items list. public List Items() { return new List(list); } /// /// Get items. /// /// Output. public void GetItems(List output) { output.AddRange(list); } /// /// Get first item. /// /// First item. public T First() { return list.First.Value; } /// /// Get last item. /// /// Last item. public T Last() { return list.Last.Value; } /// /// Removes all elements that match the conditions defined by the specified predicate from a LinkedHashSet{T} collection. /// /// The number of elements that were removed from the LinkedHashSet{T} collection. /// The Predicate{T} delegate that defines the conditions of the elements to remove. public int RemoveWhere(Predicate match) { var result = 0; var keys = new List(dict.Keys); foreach (var item in keys) { if (match(item)) { Remove(item); result += 1; } } return result; } #region ICollection implementation /// /// Adds an object to the LinkedHashSet{T}. /// /// The object to add to the LinkedHashSet{T}. public void Add(T item) { if (!dict.ContainsKey(item)) { list.AddLast(item); dict.Add(item, list.Last); } } /// /// Removes all items from the LinkedHashSet{T}. /// public void Clear() { dict.Clear(); list.Clear(); } /// /// Determines whether the LinkedHashSet{T} contains a specific value. /// /// true if item is found in the LinkedHashSet{T}; otherwise, false. /// The object to locate in the LinkedHashSet{T}. public bool Contains(T item) { return dict.ContainsKey(item); } /// /// Copies the elements of the LinkedHashSet{T} to an Array, starting at a particular Array index. /// /// The one-dimensional Array that is the destination of the elements copied from LinkedHashSet{T}. The Array must have zero-based indexing. /// The zero-based index in array at which copying begins. public void CopyTo(T[] array, int arrayIndex) { list.CopyTo(array, arrayIndex); } /// /// Removes the first occurrence of a specific object from the LinkedHashSet{T}. /// /// true if the element is successfully found and removed; otherwise, false. This method returns false if item is not found in the LinkedHashSet{T} object. /// The object to remove from the LinkedHashSet{T}. public bool Remove(T item) { if (dict.ContainsKey(item)) { list.Remove(dict[item]); dict.Remove(item); return true; } return false; } /// /// Gets the number of elements contained in the LinkedHashSet{T}. /// /// The number of elements contained in the LinkedHashSet{T}. public int Count { get { return dict.Count; } } /// /// Gets a value indicating whether the LinkedHashSet{T} is read only. /// /// true if the LinkedHashSet{T} is read only; otherwise, false. public bool IsReadOnly { get { return false; } } #endregion #region IEnumerable implementation /// /// Returns an enumerator that iterates through the collection. /// /// An enumerator that can be used to iterate through the collection. public LinkedList.Enumerator GetEnumerator() { return list.GetEnumerator(); } /// /// Returns an enumerator that iterates through the collection. /// /// An enumerator that can be used to iterate through the collection. [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "HAA0601:Value type to reference type conversion causing boxing allocation", Justification = "Required.")] IEnumerator IEnumerable.GetEnumerator() { return list.GetEnumerator(); } #endregion #region IEnumerable implementation /// /// Returns an enumerator that iterates through the collection. /// /// An enumerator that can be used to iterate through the collection. [System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "HAA0601:Value type to reference type conversion causing boxing allocation", Justification = "Required.")] IEnumerator IEnumerable.GetEnumerator() { return list.GetEnumerator(); } #endregion } }