.net 3.5中的hashset用起来非常顺手,特别是元素数量不少(也不太多)又需要频繁进行搜索操作的时候。
最在 .net2.0 环境 + vs2008 下用了 LinqBridge (use linq in .net 2.0),觉得可以类似地可以写一个2.0的hashset,放在System.Collections.Generic命名空间里,在2.0的程序里引用,这样以后迁移到3.5+只要把引用去掉就可以了。 这个hashset通过封装Dictionary<TKey,TValue>实现。
using System;
using System.Collections;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.Security;
using System.Collections.Generic;
namespace System.Collections.Generic
{
/// <summary>
/// 在.net2.0环境下提供HashSet(Of T)类型的模拟实现
/// </summary>
/// <typeparam name="T">集合中的元素类型</typeparam>
public class HashSet<T> : ICollection<T>, IEnumerable<T>, IEnumerable, ISerializable, IDeserializationCallback
{
private readonly Dictionary<T, object> dict;
#region constructors
/// <summary>
/// Initializes a new instance of the System.Collections.Generic.HashSet<T> class
/// that is empty and uses the default equality comparer for the set type.
/// </summary>
public HashSet()
{
this.dict = new Dictionary<T, object>();
}
/// <summary>
/// Initializes a new instance of the System.Collections.Generic.HashSet<T> 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.
/// </summary>
/// <param name="collection">The collection whose elements are copied to the new set.</param>
/// <exception cref="ArgumentNullException">collection is null.</exception>
public HashSet(IEnumerable<T> collection)
{
if (collection == null)
throw new ArgumentNullException("collection");
this.dict = new Dictionary<T, object>();
foreach (T item in collection)
this.dict[item] = null;
}
/// <summary>
/// Initializes a new instance of the System.Collections.Generic.HashSet<T> class
/// that is empty and uses the specified equality comparer for the set type.
/// </summary>
/// <param name="comparer">
/// The System.Collections.Generic.IEqualityComparer<T> implementation to use
/// when comparing values in the set, or null to use the default System.Collections.Generic.EqualityComparer<T>
/// implementation for the set type.
/// </param>
public HashSet(IEqualityComparer<T> comparer)
{
this.dict = new Dictionary<T, object>(comparer);
}
/// <summary>
/// Initializes a new instance of the System.Collections.Generic.HashSet<T> 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.
/// </summary>
/// <param name="collection">The collection whose elements are copied to the new set.</param>
/// <param name="comparer">
/// The System.Collections.Generic.IEqualityComparer<T> implementation to use
/// when comparing values in the set, or null to use the default System.Collections.Generic.EqualityComparer<T>
/// implementation for the set type.
/// </param>
/// <exception cref="ArgumentNullException">collection is null.</exception>
public HashSet(IEnumerable<T> collection, IEqualityComparer<T> comparer)
{
if (collection == null)
throw new ArgumentNullException("collection");
this.dict = new Dictionary<T, object>(comparer);
foreach (T item in collection)
this.dict[item] = null;
}
#endregion
#region properties
/// <summary>
/// Gets the System.Collections.Generic.IEqualityComparer<T> object that is used
/// to determine equality for the values in the set.
/// </summary>
public IEqualityComparer<T> Comparer { get { return this.dict.Comparer; } }
/// <summary>
/// Gets the number of elements that are contained in a set.
/// </summary>
public int Count { get { return this.dict.Count; } }
#endregion
#region methods
/// <summary>
/// Adds the specified element to a set.
/// </summary>
/// <param name="item">The element to add to the set.</param>
/// <returns>
/// true if the element is added to the System.Collections.Generic.HashSet<T> object;
/// false if the element is already present.
/// </returns