我真的想在我的程序中使用hashsets.使用字典感觉很难看.我可能有一天会开始使用VS2008和.Net 3.5,所以我的理想是即使我不能(或者我可以?)在VS2005中使用hashsets,当我开始使用.NET 3.5时,我不想要必须改变很多,如果有的话,以便切换到使用这些hashsets.
我想知道是否有人知道为此设计的现有hashset实现,或者在VS2005中使用3.5 hashset的方法.
这是我为2.0编写的一个内部使用Dictionary
using System; using System.Collections; using System.Collections.Generic; using System.Runtime.Serialization; public class HashSet: ICollection , ISerializable, IDeserializationCallback { private readonly Dictionary dict; public HashSet() { dict = new Dictionary (); } public HashSet(IEnumerable items) : this() { if (items == null) { return; } foreach (T item in items) { Add(item); } } public HashSet NullSet { get { return new HashSet (); } } #region ICollection Members public void Add(T item) { if (null == item) { throw new ArgumentNullException("item"); } dict[item] = null; } /// /// Removes all items from the ///. /// The public void Clear() { dict.Clear(); } public bool Contains(T item) { return dict.ContainsKey(item); } ///is read-only. /// Copies the items of the /// The one-dimensionalto an , starting at a particular index. /// that is the destination of the items copied from . The must have zero-based indexing.The zero-based index in at which copying begins. is null. is less than 0. public void CopyTo(T[] array, int arrayIndex) { if (array == null) throw new ArgumentNullException("array"); if (arrayIndex < 0 || arrayIndex >= array.Length || arrayIndex >= Count) { throw new ArgumentOutOfRangeException("arrayIndex"); } dict.Keys.CopyTo(array, arrayIndex); } /// is multidimensional.-or- is equal to or greater than the length of .-or-The number of items in the source is greater than the available space from to the end of the destination .-or-Type T cannot be cast automatically to the type of the destination . /// Removes the first occurrence of a specific object from the ///. /// /// true if /// The object to remove from thewas successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . /// . The public bool Remove(T item) { return dict.Remove(item); } ///is read-only. /// Gets the number of items contained in the ///. /// /// The number of items contained in the public int Count { get { return dict.Count; } } ///. /// /// Gets a value indicating whether the ///is read-only. /// /// true if the public bool IsReadOnly { get { return false; } } #endregion public HashSetis read-only; otherwise, false. /// Union(HashSet set) { HashSet unionSet = new HashSet (this); if (null == set) { return unionSet; } foreach (T item in set) { if (unionSet.Contains(item)) { continue; } unionSet.Add(item); } return unionSet; } public HashSet Subtract(HashSet set) { HashSet subtractSet = new HashSet (this); if (null == set) { return subtractSet; } foreach (T item in set) { if (!subtractSet.Contains(item)) { continue; } subtractSet.dict.Remove(item); } return subtractSet; } public bool IsSubsetOf(HashSet set) { HashSet setToCompare = set ?? NullSet; foreach (T item in this) { if (!setToCompare.Contains(item)) { return false; } } return true; } public HashSet Intersection(HashSet set) { HashSet intersectionSet = NullSet; if (null == set) { return intersectionSet; } foreach (T item in this) { if (!set.Contains(item)) { continue; } intersectionSet.Add(item); } foreach (T item in set) { if (!Contains(item) || intersectionSet.Contains(item)) { continue; } intersectionSet.Add(item); } return intersectionSet; } public bool IsProperSubsetOf(HashSet set) { HashSet setToCompare = set ?? NullSet; // A is a proper subset of a if the b is a subset of a and a != b return (IsSubsetOf(setToCompare) && !setToCompare.IsSubsetOf(this)); } public bool IsSupersetOf(HashSet set) { HashSet setToCompare = set ?? NullSet; foreach (T item in setToCompare) { if (!Contains(item)) { return false; } } return true; } public bool IsProperSupersetOf(HashSet set) { HashSet setToCompare = set ?? NullSet; // B is a proper superset of a if b is a superset of a and a != b return (IsSupersetOf(setToCompare) && !setToCompare.IsSupersetOf(this)); } public List ToList() { return new List (this); } #region Implementation of ISerializable /// /// Populates a /// Thewith the data needed to serialize the target object. /// 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 Implementation of 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) { dict.OnDeserialization(sender); } #endregion #region Implementation of IEnumerable ////// Returns an enumerator that iterates through the collection. /// ////// A ///that can be used to iterate through the collection. /// 1 public IEnumeratorGetEnumerator() { return dict.Keys.GetEnumerator(); } /// /// Returns an enumerator that iterates through a collection. /// ////// An ///object that can be used to iterate through the collection. /// 2 IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion }
您HashSet
现在可以在2.0应用程序中使用- 只需参考System.Core.dll,您应该很高兴.
注意:这将要求您安装免费且独立于Visual Studio 的.NET 3.5框架.安装完成后,您将拥有包含该HashSet
类型的新System.Core程序集.由于.NET框架版本2.0 - 3.5都共享相同的CLR,因此您可以在2.0应用程序中使用此程序集而不会出现任何问题.
你可以使用Iesi.Collections(由NHibernate使用)或Mono的HashSet