//GNU Library General Public License (LGPL)
//http://dac.codeplex.com/license
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Security;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
namespace RaisingStudio.Collections.Generic
{
[Serializable]
public class HashSet<T> : ICollection<T>, IEnumerable<T>, IEnumerable, ISerializable, IDeserializationCallback
{
private const string CapacityName = "Capacity";
private const string ComparerName = "Comparer";
private const string ElementsName = "Elements";
private const int GrowthFactor = 2;
private const int Lower31BitMask = 0x7fffffff;
private int[] m_buckets;
private IEqualityComparer<T> m_comparer;
private int m_count;
private int m_freeList;
private int m_lastIndex;
private Slot<T>[] m_slots;
private int m_version;
private const int ShrinkThreshold = 3;
private const int StackAllocThreshold = 100;
private const string VersionName = "Version";
public HashSet()
: this(EqualityComparer<T>.Default)
{
}
public HashSet(IEnumerable<T> collection)
: this(collection, EqualityComparer<T>.Default)
{
}
public HashSet(IEqualityComparer<T> comparer)
{
if (comparer == null)
{
comparer = EqualityComparer<T>.Default;
}
this.m_comparer = comparer;
this.m_lastIndex = 0;
this.m_count = 0;
this.m_freeList = -1;
this.m_version = 0;
}
public HashSet(IEnumerable<T> collection, IEqualityComparer<T> comparer)
: this(comparer)
{
if (collection == null)
{
throw new ArgumentNullException("collection");
}
int capacity = 0;
ICollection<T> is2 = collection as ICollection<T>;
if (is2 != null)
{
capacity = is2.Count;
}
this.Initialize(capacity);
this.UnionWith(collection);
if (((this.m_count == 0) && (this.m_slots.Length > HashHelpers.GetMinPrime())) || ((this.m_count > 0) && ((this.m_slots.Length / this.m_count) > 3)))
{
this.TrimExcess();
}
}
private SerializationInfo m_siInfo;
protected HashSet(SerializationInfo info, StreamingContext context)
{
this.m_siInfo = info;
}
public bool Add(T item)
{
return this.AddIfNotPresent(item);
}
private bool AddIfNotPresent(T value)
{
int freeList;
if (this.m_buckets == null)
{
this.Initialize(0);
}
int hashCode = this.InternalGetHashCode(value);
int index = hashCode % this.m_buckets.Length;
for (int i = this.m_buckets[hashCode % this.m_buckets.Length] - 1; i >= 0; i = this.m_slots[i].next)
{
if ((this.m_slots[i].hashCode == hashCode) && this.m_comparer.Equals(this.m_slots[i].value, value))
{
return false;
}
}
if (this.m_freeList >= 0)
{
freeList = this.m_freeList;
this.m_freeList = this.m_slots[freeList].next;
}
else
{
if (this.m_lastIndex == this.m_slots.Length)
{
this.IncreaseCapacity();
index = hashCode % this.m_buckets.Length;
}
freeList = this.m_lastIndex;
this.m_lastIndex++;
}
this.m_slots[freeList].hashCode = hashCode;
this.m_slots[freeList].value = value;
this.m_slots[freeList].next = this.m_buckets[index] - 1;
this.m_buckets[index] = freeList + 1;
this.m_count++;
this.m_version++;
return true;
}
private bool AddOrGetLocation(T value, out int location)
{
int freeList;
int hashCode = this.InternalGetHashCode(value);
int index = hashCode % this.m_buckets.Length;
for (int i = this.m_buckets[hashCode % this.m_buckets.Length] - 1; i >= 0; i = this.m_slots[i].next)
{
if ((this.m_slots[i].hashCode == hashCode) && this.m_comparer.Equals(this.m_slots[i].value, value))
{
location = i;
return false;
}
}
if (this.m_freeList >= 0)
{
freeList = this.m_freeList;
this.m_freeList = this.m_slots[freeList].next;
}
else
{
if (this.m_lastIndex == this.m_slots.Length)
{
this.IncreaseCapacity();
index = hashCode % this.m_buckets.Length;
}
freeList = this.m_lastIndex;
this.m_lastIndex++;
}
this.m_slots[freeList].hashCode = hashCode;
this.m_slots[freeList].value = value;
this.m_slots[freeList].next = this.m_buckets[index] - 1;
this.m_buckets[index] = freeList + 1;
this.m_count++;
this.m_version++;
location = freeList;
return true;
}
private static bool AreEqualityComparersEqual(HashSet<T> set1, HashSet<T> set2)
{
return set1.Comparer.Equals(set2.Comparer);
}
[SecurityCritical]
private unsafe ElementCount<T> CheckUniqueAndUnfoundElements(IEnumerable<T> other, bool returnIfUnfound)
{
ElementCount<T> count;
if (this.m_count != 0)
{
BitHelper helper;
int length = BitHelper.ToIntArrayLength(this.m_lastIndex);
if (length <= 100)
{
int* bitArrayPtr = stackalloc int[length];
helper = new BitHelper(bitArrayPtr, length);
}
else
{
int[] bitArray = new int[length];
helper = new BitHelper(bitArray, length);
}
int num4 = 0;
int num5 = 0;
foreach (T local in other)
{
int bitPosition = this.InternalIndexOf(local);
if (bitPosition >= 0)
{
if (!helper.IsMarked(bitPosition))
{
helper.MarkBit(bitPosition);
num5++;
}
}
else
{
num4++;
if (returnIfUnfound)
{
break;
}
}
}
count.uniqueCount = num5;
count.unfoundCount = num4;
return count;
}
int num = 0;
using (IEnumerator<T> enumerator = other.GetEnumerator())
{
while (enumerator.MoveNext())
{
T current = enumerator.Current;
num++;
goto Label_0039;
}
}
Label_0039:
count.uniqueCount = 0;
count.unfoundCount = num;
return count;
}
public void Clear()
{
if (this.m_lastIndex > 0)
{
Array.Clear(this.m_slots, 0, this.m_lastIndex);
Array.Clear(this.m_buckets, 0, this.m_buckets.Length);
this.m_lastIndex = 0;
this.m_count = 0;
this.m_freeList = -1;
}
this.m_version++;
}
public bool Contains(T item)
{
if (this.m_buckets != null)
{
int hashCode = this.InternalGetHashCode(item);
for (int i = this.m_buckets[hashCode % this.m_buckets.Length] - 1; i >= 0; i = this.m_slots[i].next)
{
if ((this.m_slots[i].hashCode == hashCode) && this.m_comparer.Equals(this.m_slots[i].value, item))
{
return true;
}
}
}
return false;
}
private bool ContainsAllElements(IEnumerable<T> other)
{
foreach (T local in other)
{
if (!this.Contains(local))
{
return false;
}
}
return true;
}
public void CopyTo(T[] array)
{
this.CopyTo(array, 0, this.m_count);
}
public void CopyTo(T[] array, int arrayIndex)
{
this.CopyTo(array, arrayIndex, this.m_count);
}
public void CopyTo(T[] array, int arrayIndex, int count)
{
if (array == null)
{
throw new ArgumentNullException("array");
}
if (arrayIndex < 0)
{
throw new ArgumentOutOfRangeException("arrayIndex", "ArgumentOutOfRange_NeedNonNegNum");
}
if (count < 0)
{
throw new ArgumentOutOfRangeException("count", "ArgumentOutOfRange_NeedNonNegNum");
}
if ((arrayIndex > array.Length) || (count > (array.Length - arrayIndex)))
{
throw new ArgumentException("Arg_ArrayPlusOffTooSmall");
}
int num = 0;
for (int i = 0; (i < this.m_lastIndex) && (num < count); i++)
{
if (this.m_slots[i].hashCode >= 0)
{
array[arrayIndex + num] = this.m_slots[i].value;
num++;
}
}
}
public static IEqualityComparer<HashSet<T>> CreateSetComparer()
{
return new HashSetEqualityComparer<T>();
}
public void ExceptWith(IEnumerable<T> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (this.m_count != 0)
{
if (other == this)
{
this.Clear();
}
else
{
foreach (T local in other)
{
this.Remove(local);
}
}
}
}
public Enumerator<T> GetEnumerator()
{
return new Enumerator<T>((HashSet<T>)this);
}
#if (PocketPC || Smartphone)
#else
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
#endif
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new ArgumentNullException("info");
}
info.AddValue("Version", this.m_version);
info.AddValue("Comparer", this.m_comparer, typeof(IEqualityComparer<T>));
info.AddValue("Capacity", (this.m_buckets == null) ? 0 : this.m_buckets.Length);
if (this.m_buckets != null)
{
T[] array = new T[this.m_count];
this.CopyTo(array);
info.AddValue("Elements", array, typeof(T[]));
}
}
internal static bool HashSetEquals(HashSet<T> set1, HashSet<T> set2, IEqualityComparer<T> comparer)
{
if (set1 == null)
{
return (set2 == null);
}
if (set2 == null)
{
return false;
}
if (HashSet<T>.AreEqualityComparersEqual(set1, set2))
{
if (set1.Count != set2.Count)
{
return false;
}
foreach (T local in set2)
{
if (!set1.Contains(local))
{
return false;
}
}
return true;
}
foreach (T local2 in set2)
{
bool flag = false;
foreach (T local3 in set1)
{
if (comparer.Equals(local2, local3))
{
flag = true;
break;
}
}
if (!flag)
{
return false;
}
}
return true;
}
private void IncreaseCapacity()
{
int min = this.m_count * 2;
if (min < 0)
{
min = this.m_count;
}
int prime = HashHelpers.GetPrime(min);
if (prime <= this.m_count)
{
throw new ArgumentException("Arg_HSCapacityOverflow");
}
Slot<T>[] destinationArray = new Slot<T>[prime];
if (this.m_slots != null)
{
Array.Copy(this.m_slots, 0, destinationArray, 0, this.m_lastIndex);
}
int[] numArray = new int[prime];
for (int i = 0; i < this.m_lastIndex; i++)
{
int index = destinationArray[i].hashCode % prime;
destinationArray[i].next = numArray[index] - 1;
numArray[index] = i + 1;
}
this.m_slots = destinationArray;
this.m_buckets = numArray;
}
private void Initialize(int capacity)
{
int prime = HashHelpers.GetPrime(capacity);
this.m_buckets = new int[prime];
this.m_slots = new Slot<T>[prime];
}
private int InternalGetHashCode(T item)
{
if (item == null)
{
return 0;
}
return (this.m_comparer.GetHashCode(item) & 0x7fffffff);
}
private int InternalIndexOf(T item)
{
int hashCode = this.InternalGetHashCode(item);
for (int i = this.m_buckets[hashCode % this.m_buckets.Length] - 1; i >= 0; i = this.m_slots[i].next)
{
if ((this.m_slots[i].hashCode == hashCode) && this.m_comparer.Equals(this.m_slots[i].value, item))
{
return i;
}
}
return -1;
}
[SecurityCritical]
public void IntersectWith(IEnumerable<T> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (this.m_count != 0)
{
ICollection<T> is2 = other as ICollection<T>;
if (is2 != null)
{
if (is2.Count == 0)
{
this.Clear();
return;
}
HashSet<T> set = other as HashSet<T>;
if ((set != null) && HashSet<T>.AreEqualityComparersEqual((HashSet<T>)this, set))
{
this.IntersectWithHashSetWithSameEC(set);
return;
}
}
this.IntersectWithEnumerable(other);
}
}
[SecurityCritical]
private unsafe void IntersectWithEnumerable(IEnumerable<T> other)
{
BitHelper helper;
int lastIndex = this.m_lastIndex;
int length = BitHelper.ToIntArrayLength(lastIndex);
if (length <= 100)
{
int* bitArrayPtr = stackalloc int[length];
helper = new BitHelper(bitArrayPtr, length);
}
else
{
int[] bitArray = new int[length];
helper = new BitHelper(bitArray, length);
}
foreach (T local in other)
{
int bitPosition = this.InternalIndexOf(local);
if (bitPosition >= 0)
{
helper.MarkBit(bitPosition);
}
}
for (int i = 0; i < lastIndex; i++)
{
if ((this.m_slots[i].hashCode >= 0) && !helper.IsMarked(i))
{
this.Remove(this.m_slots[i].value);
}
}
}
private void IntersectWithHashSetWithSameEC(HashSet<T> other)
{
for (int i = 0; i < this.m_lastIndex; i++)
{
if (this.m_slots[i].hashCode >= 0)
{
T item = this.m_slots[i].value;
if (!other.Contains(item))
{
this.Remove(item);
}
}
}
}
[SecurityCritical]
public bool IsProperSubsetOf(IEnumerable<T> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
ICollection<T> is2 = other as ICollection<T>;
if (is2 != null)
{
if (this.m_count == 0)
{
return (is2.Count > 0);
}
HashSet<T> set = other as HashSet<T>;
if ((set != null) && HashSet<T>.AreEqualityComparersEqual((HashSet<T>)this, set))
{
if (this.m_count >= set.Count)
{
return false;
}
return this.IsSubsetOfHashSetWithSameEC(set);
}
}
ElementCount<T> count = this.CheckUniqueAndUnfoundElements(other, false);
return ((count.uniqueCount == this.m_count) && (count.unfoundCount > 0));
}
[SecurityCritical]
public bool IsProperSupersetOf(IEnumerable<T> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (this.m_count == 0)
{
return false;
}
ICollection<T> is2 = other as ICollection<T>;
if (is2 != null)
{
if (is2.Count == 0)
{
return true;
}
HashSet<T> set = other as HashSet<T>;
if ((set != null) && HashSet<T>.AreEqualityComparersEqual((HashSet<T>)this, set))
{
if (set.Count >= this.m_count)
{
return false;
}
return this.ContainsAllElements(set);
}
}
ElementCount<T> count = this.CheckUniqueAndUnfoundElements(other, true);
return ((count.uniqueCount < this.m_count) && (count.unfoundCount == 0));
}
[SecurityCritical]
public bool IsSubsetOf(IEnumerable<T> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (this.m_count == 0)
{
return true;
}
HashSet<T> set = other as HashSet<T>;
if ((set != null) && HashSet<T>.AreEqualityComparersEqual((HashSet<T>)this, set))
{
if (this.m_count > set.Count)
{
return false;
}
return this.IsSubsetOfHashSetWithSameEC(set);
}
ElementCount<T> count = this.CheckUniqueAndUnfoundElements(other, false);
return ((count.uniqueCount == this.m_count) && (count.unfoundCount >= 0));
}
private bool IsSubsetOfHashSetWithSameEC(HashSet<T> other)
{
foreach (T local in this)
{
if (!other.Contains(local))
{
return false;
}
}
return true;
}
public bool IsSupersetOf(IEnumerable<T> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
ICollection<T> is2 = other as ICollection<T>;
if (is2 != null)
{
if (is2.Count == 0)
{
return true;
}
HashSet<T> set = other as HashSet<T>;
if (((set != null) && HashSet<T>.AreEqualityComparersEqual((HashSet<T>)this, set)) && (set.Count > this.m_count))
{
return false;
}
}
return this.ContainsAllElements(other);
}
public virtual void OnDeserialization(object sender)
{
if (this.m_siInfo != null)
{
int num = this.m_siInfo.GetInt32("Capacity");
this.m_comparer = (IEqualityComparer<T>)this.m_siInfo.GetValue("Comparer", typeof(IEqualityComparer<T>));
this.m_freeList = -1;
if (num != 0)
{
this.m_buckets = new int[num];
this.m_slots = new Slot<T>[num];
T[] localArray = (T[])this.m_siInfo.GetValue("Elements", typeof(T[]));
if (localArray == null)
{
throw new SerializationException("Serialization_MissingKeys");
}
for (int i = 0; i < localArray.Length; i++)
{
this.AddIfNotPresent(localArray[i]);
}
}
else
{
this.m_buckets = null;
}
this.m_version = this.m_siInfo.GetInt32("Version");
this.m_siInfo = null;
}
}
public bool Overlaps(IEnumerable<T> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (this.m_count != 0)
{
foreach (T local in other)
{
if (this.Contains(local))
{
return true;
}
}
}
return false;
}
public bool Remove(T item)
{
if (this.m_buckets != null)
{
int hashCode = this.InternalGetHashCode(item);
int index = hashCode % this.m_buckets.Length;
int num3 = -1;
for (int i = this.m_buckets[index] - 1; i >= 0; i = this.m_slots[i].next)
{
if ((this.m_slots[i].hashCode == hashCode) && this.m_comparer.Equals(this.m_slots[i].value, item))
{
if (num3 < 0)
{
this.m_buckets[index] = this.m_slots[i].next + 1;
}
else
{
this.m_slots[num3].next = this.m_slots[i].next;
}
this.m_slots[i].hashCode = -1;
this.m_slots[i].value = default(T);
this.m_slots[i].next = this.m_freeList;
this.m_freeList = i;
this.m_count--;
this.m_version++;
return true;
}
num3 = i;
}
}
return false;
}
public int RemoveWhere(Predicate<T> match)
{
if (match == null)
{
throw new ArgumentNullException("match");
}
int num = 0;
for (int i = 0; i < this.m_lastIndex; i++)
{
if (this.m_slots[i].hashCode >= 0)
{
T local = this.m_slots[i].value;
if (match(local) && this.Remove(local))
{
num++;
}
}
}
return num;
}
[SecurityCritical]
public bool SetEquals(IEnumerable<T> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
HashSet<T> set = other as HashSet<T>;
if ((set != null) && HashSet<T>.AreEqualityComparersEqual((HashSet<T>)this, set))
{
if (this.m_count != set.Count)
{
return false;
}
return this.ContainsAllElements(set);
}
ICollection<T> is2 = other as ICollection<T>;
if (((is2 != null) && (this.m_count == 0)) && (is2.Count > 0))
{
return false;
}
ElementCount<T> count = this.CheckUniqueAndUnfoundElements(other, true);
return ((count.uniqueCount == this.m_count) && (count.unfoundCount == 0));
}
[SecurityCritical]
public void SymmetricExceptWith(IEnumerable<T> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
if (this.m_count == 0)
{
this.UnionWith(other);
}
else if (other == this)
{
this.Clear();
}
else
{
HashSet<T> set = other as HashSet<T>;
if ((set != null) && HashSet<T>.AreEqualityComparersEqual((HashSet<T>)this, set))
{
this.SymmetricExceptWithUniqueHashSet(set);
}
else
{
this.SymmetricExceptWithEnumerable(other);
}
}
}
[SecurityCritical]
private unsafe void SymmetricExceptWithEnumerable(IEnumerable<T> other)
{
BitHelper helper;
BitHelper helper2;
int lastIndex = this.m_lastIndex;
int length = BitHelper.ToIntArrayLength(lastIndex);
if (length <= 50)
{
int* bitArrayPtr = stackalloc int[length];
helper = new BitHelper(bitArrayPtr, length);
int* numPtr2 = stackalloc int[length];
helper2 = new BitHelper(numPtr2, length);
}
else
{
int[] bitArray = new int[length];
helper = new BitHelper(bitArray, length);
int[] numArray2 = new int[length];
helper2 = new BitHelper(numArray2, length);
}
foreach (T local in other)
{
int location = 0;
if (this.AddOrGetLocation(local, out location))
{
helper2.MarkBit(location);
}
else if ((location < lastIndex) && !helper2.IsMarked(location))
{
helper.MarkBit(location);
}
}
for (int i = 0; i < lastIndex; i++)
{
if (helper.IsMarked(i))
{
this.Remove(this.m_slots[i].value);
}
}
}
private void SymmetricExceptWithUniqueHashSet(HashSet<T> other)
{
foreach (T local in other)
{
if (!this.Remove(local))
{
this.AddIfNotPresent(local);
}
}
}
void ICollection<T>.Add(T item)
{
this.AddIfNotPresent(item);
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return new Enumerator<T>((HashSet<T>)this);
}
IEnumerator IEnumerable.GetEnumerator()
{
return new Enumerator<T>((HashSet<T>)this);
}
internal T[] ToArray()
{
T[] array = new T[this.Count];
this.CopyTo(array);
return array;
}
public void TrimExcess()
{
if (this.m_count == 0)
{
this.m_buckets = null;
this.m_slots = null;
this.m_version++;
}
else
{
int prime = HashHelpers.GetPrime(this.m_count);
Slot<T>[] slotArray = new Slot<T>[prime];
int[] numArray = new int[prime];
int index = 0;
for (int i = 0; i < this.m_lastIndex; i++)
{
if (this.m_slots[i].hashCode >= 0)
{
slotArray[index] = this.m_slots[i];
int num4 = slotArray[index].hashCode % prime;
slotArray[index].next = numArray[num4] - 1;
numArray[num4] = index + 1;
index++;
}
}
this.m_lastIndex = index;
this.m_slots = slotArray;
this.m_buckets = numArray;
this.m_freeList = -1;
}
}
public void UnionWith(IEnumerable<T> other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
foreach (T local in other)
{
this.AddIfNotPresent(local);
}
}
public IEqualityComparer<T> Comparer
{
get
{
return this.m_comparer;
}
}
public int Count
{
get
{
return this.m_count;
}
}
bool ICollection<T>.IsReadOnly
{
get
{
return false;
}
}
[StructLayout(LayoutKind.Sequential)]
internal struct ElementCount<T>
{
internal int uniqueCount;
internal int unfoundCount;
}
[Serializable, StructLayout(LayoutKind.Sequential)]
#if (PocketPC || Smartphone)
#else
[HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]
#endif
public struct Enumerator<T> : IEnumerator<T>, IDisposable, IEnumerator
{
private HashSet<T> set;
private int index;
private int version;
private T current;
internal Enumerator(HashSet<T> set)
{
this.set = set;
this.index = 0;
this.version = set.m_version;
this.current = default(T);
}
public void Dispose()
{
}
public bool MoveNext()
{
if (this.version != this.set.m_version)
{
throw new InvalidOperationException("InvalidOperation_EnumFailedVersion");
}
while (this.index < this.set.m_lastIndex)
{
if (this.set.m_slots[this.index].hashCode >= 0)
{
this.current = this.set.m_slots[this.index].value;
this.index++;
return true;
}
this.index++;
}
this.index = this.set.m_lastIndex + 1;
this.current = default(T);
return false;
}
public T Current
{
get
{
return this.current;
}
}
object IEnumerator.Current
{
get
{
if ((this.index == 0) || (this.index == (this.set.m_lastIndex + 1)))
{
throw new InvalidOperationException("InvalidOperation_EnumOpCantHappen");
}
return this.Current;
}
}
void IEnumerator.Reset()
{
if (this.version != this.set.m_version)
{
throw new InvalidOperationException("InvalidOperation_EnumFailedVersion");
}
this.index = 0;
this.current = default(T);
}
}
[StructLayout(LayoutKind.Sequential)]
internal struct Slot<T>
{
internal int hashCode;
internal T value;
internal int next;
}
}
[Serializable]
internal class HashSetEqualityComparer<T> : IEqualityComparer<HashSet<T>>
{
private IEqualityComparer<T> m_comparer;
public HashSetEqualityComparer()
{
this.m_comparer = EqualityComparer<T>.Default;
}
public HashSetEqualityComparer(IEqualityComparer<T> comparer)
{
if (this.m_comparer == null)
{
this.m_comparer = EqualityComparer<T>.Default;
}
else
{
this.m_comparer = comparer;
}
}
public override bool Equals(object obj)
{
HashSetEqualityComparer<T> comparer = obj as HashSetEqualityComparer<T>;
if (comparer == null)
{
return false;
}
return (this.m_comparer == comparer.m_comparer);
}
public bool Equals(HashSet<T> x, HashSet<T> y)
{
return HashSet<T>.HashSetEquals(x, y, this.m_comparer);
}
public override int GetHashCode()
{
return this.m_comparer.GetHashCode();
}
public int GetHashCode(HashSet<T> obj)
{
int num = 0;
if (obj != null)
{
foreach (T local in obj)
{
num ^= this.m_comparer.GetHashCode(local) & 0x7fffffff;
}
}
return num;
}
}
}
|