using System; using System.Collections; using System.Diagnostics; using System.Runtime.Serialization; using System.Security; using System.Collections.Generic; namespace Thousandto.Core.Base { /// /// 在.net2.0环境下提供HashSet(Of T)类型的模拟实现 /// /// 集合中的元素类型 public class HashSet : ICollection, IEnumerable, IEnumerable, ISerializable, IDeserializationCallback { private readonly Dictionary dict; #region constructors /// /// Initializes a new instance of the System.Collections.Generic.HashSet class /// that is empty and uses the default equality comparer for the set type. /// public HashSet() { this.dict = new Dictionary(); } /// /// Initializes a new instance of the System.Collections.Generic.HashSet class /// that uses the default equality comparer for the set type, contains elements /// copied from the specified collection, and has sufficient capacity to accommodate /// the number of elements copied. /// /// The collection whose elements are copied to the new set. /// collection is null. public HashSet(IEnumerable collection) { if (collection == null) throw new ArgumentNullException("collection"); this.dict = new Dictionary(); foreach (T item in collection) this.dict[item] = null; } /// /// Initializes a new instance of the System.Collections.Generic.HashSet class /// that is empty and uses the specified equality comparer for the set type. /// /// /// The System.Collections.Generic.IEqualityComparer implementation to use /// when comparing values in the set, or null to use the default System.Collections.Generic.EqualityComparer /// implementation for the set type. /// public HashSet(IEqualityComparer comparer) { this.dict = new Dictionary(comparer); } /// /// Initializes a new instance of the System.Collections.Generic.HashSet class /// that uses the specified equality comparer for the set type, contains elements /// copied from the specified collection, and has sufficient capacity to accommodate /// the number of elements copied. /// /// The collection whose elements are copied to the new set. /// /// The System.Collections.Generic.IEqualityComparer implementation to use /// when comparing values in the set, or null to use the default System.Collections.Generic.EqualityComparer /// implementation for the set type. /// /// collection is null. public HashSet(IEnumerable collection, IEqualityComparer comparer) { if (collection == null) throw new ArgumentNullException("collection"); this.dict = new Dictionary(comparer); foreach (T item in collection) this.dict[item] = null; } #endregion #region properties /// /// Gets the System.Collections.Generic.IEqualityComparer object that is used /// to determine equality for the values in the set. /// public IEqualityComparer Comparer { get { return this.dict.Comparer; } } /// /// Gets the number of elements that are contained in a set. /// public int Count { get { return this.dict.Count; } } #endregion #region methods /// /// Adds the specified element to a set. /// /// The element to add to the set. /// /// true if the element is added to the System.Collections.Generic.HashSet object; /// false if the element is already present. /// public bool Add(T item) { if (this.dict.ContainsKey(item)) { return false; } else { this.dict[item] = null; return true; } } /// /// Removes all elements from a System.Collections.Generic.HashSet object. /// public void Clear() { this.dict.Clear(); } /// /// Determines whether a System.Collections.Generic.HashSet object contains the specified element. /// /// The element to locate in the System.Collections.Generic.HashSet object. /// true if the System.Collections.Generic.HashSet object contains the specified element; otherwise, false. public bool Contains(T item) { return this.dict.ContainsKey(item); } /// /// Copies the elements of a System.Collections.Generic.HashSet object to an array. /// /// /// The one-dimensional array that is the destination of the elements copied /// from the System.Collections.Generic.HashSet object. The array must have /// zero-based indexing. /// /// array is null. public void CopyTo(T[] array) { if (array == null) throw new ArgumentNullException("array"); this.dict.Keys.CopyTo(array, 0); } /// /// Copies the elements of a System.Collections.Generic.HashSet object to an array, starting at the specified array index. /// /// /// The one-dimensional array that is the destination of the elements copied /// from the System.Collections.Generic.HashSet object. The array must have /// zero-based indexing. /// /// The zero-based index in array at which copying begins. /// array is null. /// arrayIndex is less than 0. /// arrayIndex is greater than the length of the destination array. -or- count is larger than the size of the destination array. public void CopyTo(T[] array, int arrayIndex) { if (array == null) throw new ArgumentNullException("array"); if (arrayIndex < 0) throw new ArgumentOutOfRangeException(); if (arrayIndex >= array.Length) throw new ArgumentException("arrayIndex is greater than the length of the destination array."); if (Count >= array.Length) throw new ArgumentException("the Count property is larger than the size of the destination array."); this.dict.Keys.CopyTo(array, arrayIndex); } /// /// Copies the specified number of elements of a System.Collections.Generic.HashSet object to an array, /// starting at the specified array index. /// /// The one-dimensional array that is the destination of the elements copied from the System.Collections.Generic.HashSet object. The array must have zero-based indexing. /// The zero-based index in array at which copying begins. /// The number of elements to copy to array. /// array is null. /// arrayIndex is less than 0. -or- count is less than 0. /// arrayIndex is greater than the length of the destination array. -or- count is greater than the available space from the index to the end of the destination array. public void CopyTo(T[] array, int arrayIndex, int count) { if (array == null) throw new ArgumentNullException("array"); if (arrayIndex < 0 || count < 0) throw new ArgumentOutOfRangeException(); if (arrayIndex >= array.Length) throw new ArgumentException("arrayIndex is greater than the length of the destination array."); if (count > array.Length - arrayIndex) throw new ArgumentException("count is greater than the available space from the index to the end of the destination array."); int copiedCount = 0; int currentIndex = arrayIndex; foreach (T item in this) { array[currentIndex] = item; currentIndex++; copiedCount++; if (copiedCount >= count) break; } } /// /// Removes all elements in the specified collection from the current System.Collections.Generic.HashSet object. /// /// The collection of items to remove from the System.Collections.Generic.HashSet object. /// other is null. public void ExceptWith(IEnumerable other) { if (other == null) throw new ArgumentNullException("other"); foreach (T item in other) this.dict.Remove(item); } /// /// Modifies the current System.Collections.Generic.HashSet object to contain /// only elements that are present in that object and in the specified collection. /// /// The collection to compare to the current System.Collections.Generic.HashSet object. public void IntersectWith(IEnumerable other) { this.dict.Clear(); foreach (T item in other) this.dict[item] = null; } /// /// Determines whether a System.Collections.Generic.HashSet object is a proper subset of the specified collection. /// /// The collection to compare to the current System.Collections.Generic.HashSet object. /// true if the System.Collections.Generic.HashSet object is a proper subset of other; otherwise, false. /// other is null. public bool IsProperSubsetOf(IEnumerable other) { return IsSubsetOf(other, true); } /// /// Determines whether a System.Collections.Generic.HashSet object is a subset of the specified collection. /// /// The collection to compare to the current System.Collections.Generic.HashSet object. /// true if the System.Collections.Generic.HashSet object is a subset of other; otherwise, false. /// other is null. public bool IsSubsetOf(IEnumerable other) { return IsSubsetOf(other, false); } private bool IsSubsetOf(IEnumerable other, bool proper) { if (other == null) throw new ArgumentNullException("other"); int elementCount = 0; int mathingCount = 0; foreach (T item in other) { elementCount++; if (this.dict.ContainsKey(item)) mathingCount++; } if (proper) return mathingCount == this.dict.Count && elementCount > this.dict.Count; else return mathingCount == this.dict.Count; } /// /// Determines whether a System.Collections.Generic.HashSet object is a proper superset of the specified collection. /// /// The collection to compare to the current System.Collections.Generic.HashSet object. /// true if the System.Collections.Generic.HashSet object is a proper superset of other; otherwise, false. /// other is null. public bool IsProperSupersetOf(IEnumerable other) { return IsSupersetOf(other, true); } /// /// Determines whether a System.Collections.Generic.HashSet object is a superset of the specified collection. /// /// The collection to compare to the current System.Collections.Generic.HashSet object. /// true if the System.Collections.Generic.HashSet object is a superset of other; otherwise, false. /// other is null. public bool IsSupersetOf(IEnumerable other) { return IsSupersetOf(other, false); } private bool IsSupersetOf(IEnumerable other, bool proper) { if (other == null) throw new ArgumentNullException("other"); int elementCount = 0; foreach (T item in other) { elementCount++; if (!this.dict.ContainsKey(item)) return false; } if (proper) return elementCount < this.dict.Count; else return true; } /// /// Determines whether the current System.Collections.Generic.HashSet object overlaps the specified collection. /// /// The collection to compare to the current System.Collections.Generic.HashSet object. /// true if the System.Collections.Generic.HashSet object and other share at least one common element; otherwise, false. /// other is null. public bool Overlaps(IEnumerable other) { if (other == null) throw new ArgumentNullException("other"); foreach (T item in other) { if (this.dict.ContainsKey(item)) return true; } return false; } /// /// Removes the specified element from a System.Collections.Generic.HashSet object. /// /// The element to remove. /// /// true if the element is successfully found and removed; otherwise, false. /// This method returns false if item is not found in the System.Collections.Generic.HashSet object. /// public bool Remove(T item) { if (this.dict.ContainsKey(item)) { this.dict.Remove(item); return true; } else { return false; } } /// /// Removes all elements that match the conditions defined by the specified predicate from a System.Collections.Generic.HashSet collection. /// /// The System.Predicate delegate that defines the conditions of the elements to remove. /// The number of elements that were removed from the System.Collections.Generic.HashSet collection. public int RemoveWhere(Predicate match) { int removeCount = 0; foreach (KeyValuePair item in this.dict) { if (match(item.Key)) { this.dict.Remove(item.Key); removeCount++; } } return removeCount; } /// /// Determines whether a System.Collections.Generic.HashSet object and the specified collection contain the same elements. /// /// The collection to compare to the current System.Collections.Generic.HashSet object. /// true if the System.Collections.Generic.HashSet object is equal to other; otherwise, false. /// other is null. public bool SetEquals(IEnumerable other) { if (other == null) throw new ArgumentNullException("other"); int containsCount = 0; foreach (T item in other) { if (!this.dict.ContainsKey(item)) return false; else containsCount++; } return containsCount == this.dict.Count; } /// /// Modifies the current System.Collections.Generic.HashSet object to contain only elements that are present either in that object or in the specified collection, but not both. /// /// The collection to compare to the current System.Collections.Generic.HashSet object. /// other is null. public void SymmetricExceptWith(IEnumerable other) { if (other == null) throw new ArgumentNullException("other"); HashSet tmpSet = new HashSet(other); foreach (T item in tmpSet) { if (this.dict.ContainsKey(item)) this.dict.Remove(item); else this.dict[item] = null; } } /// /// Sets the capacity of a System.Collections.Generic.HashSet object to the /// actual number of elements it contains, rounded up to a nearby, implementation-specific /// value. /// public void TrimExcess() { //do nothing } /// /// Modifies the current System.Collections.Generic.HashSet object to contain /// all elements that are present in both itself and in the specified collection. /// /// The collection to compare to the current System.Collections.Generic.HashSet object. /// other is null. public void UnionWith(IEnumerable other) { if (other == null) throw new ArgumentNullException("other"); foreach (T item in other) if (!this.dict.ContainsKey(item)) this.dict[item] = null; } #endregion #region ICollection, IEnumerable, IEnumerable成员 /// /// Returns an enumerator that iterates through a System.Collections.Generic.HashSet object. /// /// A System.Collections.Generic.HashSet.Enumerator object for the System.Collections.Generic.HashSet object. IEnumerator IEnumerable.GetEnumerator() { return this.dict.Keys.GetEnumerator(); } void ICollection.Add(T item) { throw new NotImplementedException(); } /// /// Gets a value indicating whether the is read-only. /// /// /// true if the is read-only; otherwise, false. /// public bool IsReadOnly { get { return false; } } /// /// Returns an enumerator that iterates through the collection. /// /// /// A that can be used to iterate through the collection. /// public IEnumerator GetEnumerator() { return this.dict.Keys.GetEnumerator(); } #endregion #region ISerializable 成员 /// /// Populates a with the data needed to serialize the target object. /// /// The to populate with data. The destination (see ) for this serialization. The caller does not have the required permission. public void GetObjectData(SerializationInfo info, StreamingContext context) { if (info == null) throw new ArgumentNullException("info"); dict.GetObjectData(info, context); } #endregion #region IDeserializationCallback 成员 /// /// Runs when the entire object graph has been deserialized. /// /// The object that initiated the callback. The functionality for this parameter is not currently implemented. public void OnDeserialization(object sender) { this.dict.OnDeserialization(sender); } #endregion #region Enumerator /// /// Enumerates the elements of a System.Collections.Generic.HashSet object. /// private struct Enumerator : IEnumerator, IDisposable, IEnumerator { /// /// Gets the element at the current position of the enumerator. /// /// The element in the System.Collections.Generic.HashSet collection at the current position of the enumerator. public T Current { get { throw new NotImplementedException(); } } /// /// Releases all resources used by a System.Collections.Generic.HashSet.Enumerator object. /// public void Dispose() { throw new NotImplementedException(); } /// /// Advances the enumerator to the next element of the System.Collections.Generic.HashSet collection. /// /// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection. /// The collection was modified after the enumerator was created. public bool MoveNext() { throw new NotImplementedException(); } public void Reset() { throw new NotImplementedException(); } object IEnumerator.Current { get { throw new NotImplementedException(); } } } #endregion } }