C#HashSet源码

作者: 好怕怕 | 来源:发表于2023-07-30 08:08 被阅读0次
    using System;
    using System.Diagnostics;
    using System.Runtime.Serialization;
    using System.Security;
    using System.Security.Permissions;
    
    namespace System.Collections.Generic
    {
        /// <summary>Represents a set of values.To browse the .NET Framework source code for this type, see the Reference Source.</summary>
        /// <typeparam name="T">The type of elements in the hash set.</typeparam>
        // Token: 0x02000095 RID: 149
        [DebuggerTypeProxy(typeof(HashSetDebugView<>))]
        [DebuggerDisplay("Count = {Count}")]
        [__DynamicallyInvokable]
        [HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]
        [Serializable]
        public class HashSet<T> : ICollection<T>, IEnumerable<T>, IEnumerable, ISerializable, IDeserializationCallback, ISet<T>, IReadOnlyCollection<T>
        {
            /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Generic.HashSet`1" /> class that is empty and uses the default equality comparer for the set type.</summary>
            // Token: 0x060003D9 RID: 985 RVA: 0x0000A158 File Offset: 0x00008358
            [__DynamicallyInvokable]
            public HashSet() : this(EqualityComparer<T>.Default)
            {
            }
    
            /// <summary>
            ///             Initializes a new instance of the <see cref="T:System.Collections.Generic.HashSet`1" /> class that is empty, but has reserved space for <paramref name="capacity" /> items and uses the default equality comparer for the set type.
            ///         </summary>
            /// <param name="capacity">The initial size of the <see cref="T:System.Collections.Generic.HashSet`1" /></param>
            // Token: 0x060003DA RID: 986 RVA: 0x0000A165 File Offset: 0x00008365
            public HashSet(int capacity) : this(capacity, EqualityComparer<T>.Default)
            {
            }
    
            /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Generic.HashSet`1" /> class that is empty and uses the specified equality comparer for the set type.</summary>
            /// <param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer`1" /> implementation to use when comparing values in the set, or <see langword="null" /> to use the default <see cref="T:System.Collections.Generic.EqualityComparer`1" /> implementation for the set type.</param>
            // Token: 0x060003DB RID: 987 RVA: 0x0000A173 File Offset: 0x00008373
            [__DynamicallyInvokable]
            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;
            }
    
            /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Generic.HashSet`1" /> 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="T:System.ArgumentNullException">
            ///         <paramref name="collection" /> is <see langword="null" />.</exception>
            // Token: 0x060003DC RID: 988 RVA: 0x0000A1A8 File Offset: 0x000083A8
            [__DynamicallyInvokable]
            public HashSet(IEnumerable<T> collection) : this(collection, EqualityComparer<T>.Default)
            {
            }
    
            /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Generic.HashSet`1" /> 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 <see cref="T:System.Collections.Generic.IEqualityComparer`1" /> implementation to use when comparing values in the set, or <see langword="null" /> to use the default <see cref="T:System.Collections.Generic.EqualityComparer`1" /> implementation for the set type.</param>
            /// <exception cref="T:System.ArgumentNullException">
            ///         <paramref name="collection" /> is <see langword="null" />.</exception>
            // Token: 0x060003DD RID: 989 RVA: 0x0000A1B8 File Offset: 0x000083B8
            [__DynamicallyInvokable]
            public HashSet(IEnumerable<T> collection, IEqualityComparer<T> comparer) : this(comparer)
            {
                if (collection == null)
                {
                    throw new ArgumentNullException("collection");
                }
                HashSet<T> hashSet = collection as HashSet<T>;
                if (hashSet != null && HashSet<T>.AreEqualityComparersEqual(this, hashSet))
                {
                    this.CopyFrom(hashSet);
                    return;
                }
                ICollection<T> collection2 = collection as ICollection<T>;
                int capacity = (collection2 == null) ? 0 : collection2.Count;
                this.Initialize(capacity);
                this.UnionWith(collection);
                if (this.m_count > 0 && this.m_slots.Length / this.m_count > 3)
                {
                    this.TrimExcess();
                }
            }
    
            // Token: 0x060003DE RID: 990 RVA: 0x0000A238 File Offset: 0x00008438
            private void CopyFrom(HashSet<T> source)
            {
                int count = source.m_count;
                if (count == 0)
                {
                    return;
                }
                int num = source.m_buckets.Length;
                int num2 = HashHelpers.ExpandPrime(count + 1);
                if (num2 >= num)
                {
                    this.m_buckets = (int[])source.m_buckets.Clone();
                    this.m_slots = (HashSet<T>.Slot[])source.m_slots.Clone();
                    this.m_lastIndex = source.m_lastIndex;
                    this.m_freeList = source.m_freeList;
                }
                else
                {
                    int lastIndex = source.m_lastIndex;
                    HashSet<T>.Slot[] slots = source.m_slots;
                    this.Initialize(count);
                    int num3 = 0;
                    for (int i = 0; i < lastIndex; i++)
                    {
                        int hashCode = slots[i].hashCode;
                        if (hashCode >= 0)
                        {
                            this.AddValue(num3, hashCode, slots[i].value);
                            num3++;
                        }
                    }
                    this.m_lastIndex = num3;
                }
                this.m_count = count;
            }
    
            /// <summary>Initializes a new instance of the <see cref="T:System.Collections.Generic.HashSet`1" /> class with serialized data.</summary>
            /// <param name="info">A <see cref="T:System.Runtime.Serialization.SerializationInfo" /> object that contains the information required to serialize the <see cref="T:System.Collections.Generic.HashSet`1" /> object.</param>
            /// <param name="context">A <see cref="T:System.Runtime.Serialization.StreamingContext" /> structure that contains the source and destination of the serialized stream associated with the <see cref="T:System.Collections.Generic.HashSet`1" /> object.</param>
            // Token: 0x060003DF RID: 991 RVA: 0x0000A317 File Offset: 0x00008517
            protected HashSet(SerializationInfo info, StreamingContext context)
            {
                this.m_siInfo = info;
            }
    
            /// <summary>
            ///   Initializes a new instance of the <see cref="T:System.Collections.Generic.HashSet`1" /> class that uses the specified equality comparer for the set type, and has sufficient capacity to accommodate <paramref name="capacity" /> elements.
            ///         </summary>
            /// <param name="capacity">The initial size of the <see cref="T:System.Collections.Generic.HashSet`1" /></param>
            /// <param name="comparer">
            ///                 The <see cref="T:System.Collections.Generic.IEqualityComparer`1" /> implementation to use when comparing values in the set, or null (Nothing in Visual Basic) to use the default <see cref="T:System.Collections.Generic.IEqualityComparer`1" /> implementation for the set type.
            ///             </param>
            // Token: 0x060003E0 RID: 992 RVA: 0x0000A326 File Offset: 0x00008526
            public HashSet(int capacity, IEqualityComparer<T> comparer) : this(comparer)
            {
                if (capacity < 0)
                {
                    throw new ArgumentOutOfRangeException("capacity");
                }
                if (capacity > 0)
                {
                    this.Initialize(capacity);
                }
            }
    
            // Token: 0x060003E1 RID: 993 RVA: 0x0000A349 File Offset: 0x00008549
            [__DynamicallyInvokable]
            void ICollection<!0>.Add(T item)
            {
                this.AddIfNotPresent(item);
            }
    
            /// <summary>Removes all elements from a <see cref="T:System.Collections.Generic.HashSet`1" /> object.</summary>
            // Token: 0x060003E2 RID: 994 RVA: 0x0000A354 File Offset: 0x00008554
            [__DynamicallyInvokable]
            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++;
            }
    
            /// <summary>Determines whether a <see cref="T:System.Collections.Generic.HashSet`1" /> object contains the specified element.</summary>
            /// <param name="item">The element to locate in the <see cref="T:System.Collections.Generic.HashSet`1" /> object.</param>
            /// <returns>
            ///     <see langword="true" /> if the <see cref="T:System.Collections.Generic.HashSet`1" /> object contains the specified element; otherwise, <see langword="false" />.</returns>
            // Token: 0x060003E3 RID: 995 RVA: 0x0000A3B4 File Offset: 0x000085B4
            [__DynamicallyInvokable]
            public bool Contains(T item)
            {
                if (this.m_buckets != null)
                {
                    int num = this.InternalGetHashCode(item);
                    for (int i = this.m_buckets[num % this.m_buckets.Length] - 1; i >= 0; i = this.m_slots[i].next)
                    {
                        if (this.m_slots[i].hashCode == num && this.m_comparer.Equals(this.m_slots[i].value, item))
                        {
                            return true;
                        }
                    }
                }
                return false;
            }
    
            /// <summary>Copies the elements of a <see cref="T:System.Collections.Generic.HashSet`1" /> object to an array, starting at the specified array index.</summary>
            /// <param name="array">The one-dimensional array that is the destination of the elements copied from the <see cref="T:System.Collections.Generic.HashSet`1" /> object. The array must have zero-based indexing.</param>
            /// <param name="arrayIndex">The zero-based index in <paramref name="array" /> at which copying begins.</param>
            /// <exception cref="T:System.ArgumentNullException">
            ///         <paramref name="array" /> is <see langword="null" />.</exception>
            /// <exception cref="T:System.ArgumentOutOfRangeException">
            ///         <paramref name="arrayIndex" /> is less than 0.</exception>
            /// <exception cref="T:System.ArgumentException">
            ///         <paramref name="arrayIndex" /> is greater than the length of the destination <paramref name="array" />.</exception>
            // Token: 0x060003E4 RID: 996 RVA: 0x0000A433 File Offset: 0x00008633
            [__DynamicallyInvokable]
            public void CopyTo(T[] array, int arrayIndex)
            {
                this.CopyTo(array, arrayIndex, this.m_count);
            }
    
            /// <summary>Removes the specified element from a <see cref="T:System.Collections.Generic.HashSet`1" /> object.</summary>
            /// <param name="item">The element to remove.</param>
            /// <returns>
            ///     <see langword="true" /> if the element is successfully found and removed; otherwise, <see langword="false" />.  This method returns <see langword="false" /> if <paramref name="item" /> is not found in the <see cref="T:System.Collections.Generic.HashSet`1" /> object.</returns>
            // Token: 0x060003E5 RID: 997 RVA: 0x0000A444 File Offset: 0x00008644
            [__DynamicallyInvokable]
            public bool Remove(T item)
            {
                if (this.m_buckets != null)
                {
                    int num = this.InternalGetHashCode(item);
                    int num2 = num % this.m_buckets.Length;
                    int num3 = -1;
                    for (int i = this.m_buckets[num2] - 1; i >= 0; i = this.m_slots[i].next)
                    {
                        if (this.m_slots[i].hashCode == num && this.m_comparer.Equals(this.m_slots[i].value, item))
                        {
                            if (num3 < 0)
                            {
                                this.m_buckets[num2] = 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_count--;
                            this.m_version++;
                            if (this.m_count == 0)
                            {
                                this.m_lastIndex = 0;
                                this.m_freeList = -1;
                            }
                            else
                            {
                                this.m_freeList = i;
                            }
                            return true;
                        }
                        num3 = i;
                    }
                }
                return false;
            }
    
            /// <summary>Gets the number of elements that are contained in a set.</summary>
            /// <returns>The number of elements that are contained in the set.</returns>
            // Token: 0x170000E3 RID: 227
            // (get) Token: 0x060003E6 RID: 998 RVA: 0x0000A596 File Offset: 0x00008796
            [__DynamicallyInvokable]
            public int Count
            {
                [__DynamicallyInvokable]
                get
                {
                    return this.m_count;
                }
            }
    
            // Token: 0x170000E4 RID: 228
            // (get) Token: 0x060003E7 RID: 999 RVA: 0x0000A59E File Offset: 0x0000879E
            [__DynamicallyInvokable]
            bool ICollection<!0>.IsReadOnly
            {
                [__DynamicallyInvokable]
                get
                {
                    return false;
                }
            }
    
            /// <summary>Returns an enumerator that iterates through a <see cref="T:System.Collections.Generic.HashSet`1" /> object.</summary>
            /// <returns>A <see cref="T:System.Collections.Generic.HashSet`1.Enumerator" /> object for the <see cref="T:System.Collections.Generic.HashSet`1" /> object.</returns>
            // Token: 0x060003E8 RID: 1000 RVA: 0x0000A5A1 File Offset: 0x000087A1
            [__DynamicallyInvokable]
            public HashSet<T>.Enumerator GetEnumerator()
            {
                return new HashSet<T>.Enumerator(this);
            }
    
            // Token: 0x060003E9 RID: 1001 RVA: 0x0000A5A9 File Offset: 0x000087A9
            [__DynamicallyInvokable]
            IEnumerator<T> IEnumerable<!0>.GetEnumerator()
            {
                return new HashSet<T>.Enumerator(this);
            }
    
            /// <summary>Returns an enumerator that iterates through a collection.</summary>
            /// <returns>An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.</returns>
            // Token: 0x060003EA RID: 1002 RVA: 0x0000A5B6 File Offset: 0x000087B6
            [__DynamicallyInvokable]
            IEnumerator IEnumerable.GetEnumerator()
            {
                return new HashSet<T>.Enumerator(this);
            }
    
            /// <summary>Implements the <see cref="T:System.Runtime.Serialization.ISerializable" /> interface and returns the data needed to serialize a <see cref="T:System.Collections.Generic.HashSet`1" /> object.</summary>
            /// <param name="info">A <see cref="T:System.Runtime.Serialization.SerializationInfo" /> object that contains the information required to serialize the <see cref="T:System.Collections.Generic.HashSet`1" /> object.</param>
            /// <param name="context">A <see cref="T:System.Runtime.Serialization.StreamingContext" /> structure that contains the source and destination of the serialized stream associated with the <see cref="T:System.Collections.Generic.HashSet`1" /> object.</param>
            /// <exception cref="T:System.ArgumentNullException">
            ///         <paramref name="info" /> is <see langword="null" />.</exception>
            // Token: 0x060003EB RID: 1003 RVA: 0x0000A5C4 File Offset: 0x000087C4
            [SecurityCritical]
            [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
            public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                if (info == null)
                {
                    throw new ArgumentNullException("info");
                }
                info.AddValue("Version", this.m_version);
                info.AddValue("Comparer", HashHelpers.GetEqualityComparerForSerialization(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[]));
                }
            }
    
            /// <summary>Implements the <see cref="T:System.Runtime.Serialization.ISerializable" /> interface and raises the deserialization event when the deserialization is complete.</summary>
            /// <param name="sender">The source of the deserialization event.</param>
            /// <exception cref="T:System.Runtime.Serialization.SerializationException">The <see cref="T:System.Runtime.Serialization.SerializationInfo" /> object associated with the current <see cref="T:System.Collections.Generic.HashSet`1" /> object is invalid.</exception>
            // Token: 0x060003EC RID: 1004 RVA: 0x0000A660 File Offset: 0x00008860
            public virtual void OnDeserialization(object sender)
            {
                if (this.m_siInfo == null)
                {
                    return;
                }
                int @int = this.m_siInfo.GetInt32("Capacity");
                this.m_comparer = (IEqualityComparer<T>)this.m_siInfo.GetValue("Comparer", typeof(IEqualityComparer<T>));
                this.m_freeList = -1;
                if (@int != 0)
                {
                    this.m_buckets = new int[@int];
                    this.m_slots = new HashSet<T>.Slot[@int];
                    T[] array = (T[])this.m_siInfo.GetValue("Elements", typeof(T[]));
                    if (array == null)
                    {
                        throw new SerializationException(SR.GetString("Serialization_MissingKeys"));
                    }
                    for (int i = 0; i < array.Length; i++)
                    {
                        this.AddIfNotPresent(array[i]);
                    }
                }
                else
                {
                    this.m_buckets = null;
                }
                this.m_version = this.m_siInfo.GetInt32("Version");
                this.m_siInfo = null;
            }
    
            /// <summary>Adds the specified element to a set.</summary>
            /// <param name="item">The element to add to the set.</param>
            /// <returns>
            ///     <see langword="true" /> if the element is added to the <see cref="T:System.Collections.Generic.HashSet`1" /> object; <see langword="false" /> if the element is already present.</returns>
            // Token: 0x060003ED RID: 1005 RVA: 0x0000A743 File Offset: 0x00008943
            [__DynamicallyInvokable]
            public bool Add(T item)
            {
                return this.AddIfNotPresent(item);
            }
    
            /// <summary>Searches the set for a given value and returns the equal value it finds, if any.</summary>
            /// <param name="equalValue">The value to search for.</param>
            /// <param name="actualValue">The value from the set that the search found, or the default value of T when the search yielded no match.</param>
            /// <returns>A value indicating whether the search was successful.</returns>
            // Token: 0x060003EE RID: 1006 RVA: 0x0000A74C File Offset: 0x0000894C
            public bool TryGetValue(T equalValue, out T actualValue)
            {
                if (this.m_buckets != null)
                {
                    int num = this.InternalIndexOf(equalValue);
                    if (num >= 0)
                    {
                        actualValue = this.m_slots[num].value;
                        return true;
                    }
                }
                actualValue = default(T);
                return false;
            }
    
            /// <summary>Modifies the current <see cref="T:System.Collections.Generic.HashSet`1" /> object to contain all elements that are present in itself, the specified collection, or both.</summary>
            /// <param name="other">The collection to compare to the current <see cref="T:System.Collections.Generic.HashSet`1" /> object.</param>
            /// <exception cref="T:System.ArgumentNullException">
            ///         <paramref name="other" /> is <see langword="null" />.</exception>
            // Token: 0x060003EF RID: 1007 RVA: 0x0000A790 File Offset: 0x00008990
            [__DynamicallyInvokable]
            public void UnionWith(IEnumerable<T> other)
            {
                if (other == null)
                {
                    throw new ArgumentNullException("other");
                }
                foreach (T value in other)
                {
                    this.AddIfNotPresent(value);
                }
            }
    
            /// <summary>Modifies the current <see cref="T:System.Collections.Generic.HashSet`1" /> object to contain only elements that are present in that object and in the specified collection.</summary>
            /// <param name="other">The collection to compare to the current <see cref="T:System.Collections.Generic.HashSet`1" /> object.</param>
            /// <exception cref="T:System.ArgumentNullException">
            ///         <paramref name="other" /> is <see langword="null" />.</exception>
            // Token: 0x060003F0 RID: 1008 RVA: 0x0000A7E8 File Offset: 0x000089E8
            [__DynamicallyInvokable]
            public void IntersectWith(IEnumerable<T> other)
            {
                if (other == null)
                {
                    throw new ArgumentNullException("other");
                }
                if (this.m_count == 0)
                {
                    return;
                }
                ICollection<T> collection = other as ICollection<T>;
                if (collection != null)
                {
                    if (collection.Count == 0)
                    {
                        this.Clear();
                        return;
                    }
                    HashSet<T> hashSet = other as HashSet<T>;
                    if (hashSet != null && HashSet<T>.AreEqualityComparersEqual(this, hashSet))
                    {
                        this.IntersectWithHashSetWithSameEC(hashSet);
                        return;
                    }
                }
                this.IntersectWithEnumerable(other);
            }
    
            /// <summary>Removes all elements in the specified collection from the current <see cref="T:System.Collections.Generic.HashSet`1" /> object.</summary>
            /// <param name="other">The collection of items to remove from the <see cref="T:System.Collections.Generic.HashSet`1" /> object.</param>
            /// <exception cref="T:System.ArgumentNullException">
            ///         <paramref name="other" /> is <see langword="null" />.</exception>
            // Token: 0x060003F1 RID: 1009 RVA: 0x0000A848 File Offset: 0x00008A48
            [__DynamicallyInvokable]
            public void ExceptWith(IEnumerable<T> other)
            {
                if (other == null)
                {
                    throw new ArgumentNullException("other");
                }
                if (this.m_count == 0)
                {
                    return;
                }
                if (other == this)
                {
                    this.Clear();
                    return;
                }
                foreach (T item in other)
                {
                    this.Remove(item);
                }
            }
    
            /// <summary>Modifies the current <see cref="T:System.Collections.Generic.HashSet`1" /> object to contain only elements that are present either in that object or in the specified collection, but not both.</summary>
            /// <param name="other">The collection to compare to the current <see cref="T:System.Collections.Generic.HashSet`1" /> object.</param>
            /// <exception cref="T:System.ArgumentNullException">
            ///         <paramref name="other" /> is <see langword="null" />.</exception>
            // Token: 0x060003F2 RID: 1010 RVA: 0x0000A8B4 File Offset: 0x00008AB4
            [__DynamicallyInvokable]
            public void SymmetricExceptWith(IEnumerable<T> other)
            {
                if (other == null)
                {
                    throw new ArgumentNullException("other");
                }
                if (this.m_count == 0)
                {
                    this.UnionWith(other);
                    return;
                }
                if (other == this)
                {
                    this.Clear();
                    return;
                }
                HashSet<T> hashSet = other as HashSet<T>;
                if (hashSet != null && HashSet<T>.AreEqualityComparersEqual(this, hashSet))
                {
                    this.SymmetricExceptWithUniqueHashSet(hashSet);
                    return;
                }
                this.SymmetricExceptWithEnumerable(other);
            }
    
            /// <summary>Determines whether a <see cref="T:System.Collections.Generic.HashSet`1" /> object is a subset of the specified collection.</summary>
            /// <param name="other">The collection to compare to the current <see cref="T:System.Collections.Generic.HashSet`1" /> object.</param>
            /// <returns>
            ///     <see langword="true" /> if the <see cref="T:System.Collections.Generic.HashSet`1" /> object is a subset of <paramref name="other" />; otherwise, <see langword="false" />.</returns>
            /// <exception cref="T:System.ArgumentNullException">
            ///         <paramref name="other" /> is <see langword="null" />.</exception>
            // Token: 0x060003F3 RID: 1011 RVA: 0x0000A90C File Offset: 0x00008B0C
            [__DynamicallyInvokable]
            public bool IsSubsetOf(IEnumerable<T> other)
            {
                if (other == null)
                {
                    throw new ArgumentNullException("other");
                }
                if (this.m_count == 0)
                {
                    return true;
                }
                HashSet<T> hashSet = other as HashSet<T>;
                if (hashSet != null && HashSet<T>.AreEqualityComparersEqual(this, hashSet))
                {
                    return this.m_count <= hashSet.Count && this.IsSubsetOfHashSetWithSameEC(hashSet);
                }
                HashSet<T>.ElementCount elementCount = this.CheckUniqueAndUnfoundElements(other, false);
                return elementCount.uniqueCount == this.m_count && elementCount.unfoundCount >= 0;
            }
    
            /// <summary>Determines whether a <see cref="T:System.Collections.Generic.HashSet`1" /> object is a proper subset of the specified collection.</summary>
            /// <param name="other">The collection to compare to the current <see cref="T:System.Collections.Generic.HashSet`1" /> object.</param>
            /// <returns>
            ///     <see langword="true" /> if the <see cref="T:System.Collections.Generic.HashSet`1" /> object is a proper subset of <paramref name="other" />; otherwise, <see langword="false" />.</returns>
            /// <exception cref="T:System.ArgumentNullException">
            ///         <paramref name="other" /> is <see langword="null" />.</exception>
            // Token: 0x060003F4 RID: 1012 RVA: 0x0000A984 File Offset: 0x00008B84
            [__DynamicallyInvokable]
            public bool IsProperSubsetOf(IEnumerable<T> other)
            {
                if (other == null)
                {
                    throw new ArgumentNullException("other");
                }
                ICollection<T> collection = other as ICollection<T>;
                if (collection != null)
                {
                    if (this.m_count == 0)
                    {
                        return collection.Count > 0;
                    }
                    HashSet<T> hashSet = other as HashSet<T>;
                    if (hashSet != null && HashSet<T>.AreEqualityComparersEqual(this, hashSet))
                    {
                        return this.m_count < hashSet.Count && this.IsSubsetOfHashSetWithSameEC(hashSet);
                    }
                }
                HashSet<T>.ElementCount elementCount = this.CheckUniqueAndUnfoundElements(other, false);
                return elementCount.uniqueCount == this.m_count && elementCount.unfoundCount > 0;
            }
    
            /// <summary>Determines whether a <see cref="T:System.Collections.Generic.HashSet`1" /> object is a superset of the specified collection.</summary>
            /// <param name="other">The collection to compare to the current <see cref="T:System.Collections.Generic.HashSet`1" /> object.</param>
            /// <returns>
            ///     <see langword="true" /> if the <see cref="T:System.Collections.Generic.HashSet`1" /> object is a superset of <paramref name="other" />; otherwise, <see langword="false" />.</returns>
            /// <exception cref="T:System.ArgumentNullException">
            ///         <paramref name="other" /> is <see langword="null" />.</exception>
            // Token: 0x060003F5 RID: 1013 RVA: 0x0000AA08 File Offset: 0x00008C08
            [__DynamicallyInvokable]
            public bool IsSupersetOf(IEnumerable<T> other)
            {
                if (other == null)
                {
                    throw new ArgumentNullException("other");
                }
                ICollection<T> collection = other as ICollection<T>;
                if (collection != null)
                {
                    if (collection.Count == 0)
                    {
                        return true;
                    }
                    HashSet<T> hashSet = other as HashSet<T>;
                    if (hashSet != null && HashSet<T>.AreEqualityComparersEqual(this, hashSet) && hashSet.Count > this.m_count)
                    {
                        return false;
                    }
                }
                return this.ContainsAllElements(other);
            }
    
            /// <summary>Determines whether a <see cref="T:System.Collections.Generic.HashSet`1" /> object is a proper superset of the specified collection.</summary>
            /// <param name="other">The collection to compare to the current <see cref="T:System.Collections.Generic.HashSet`1" /> object. </param>
            /// <returns>
            ///     <see langword="true" /> if the <see cref="T:System.Collections.Generic.HashSet`1" /> object is a proper superset of <paramref name="other" />; otherwise, <see langword="false" />.</returns>
            /// <exception cref="T:System.ArgumentNullException">
            ///         <paramref name="other" /> is <see langword="null" />.</exception>
            // Token: 0x060003F6 RID: 1014 RVA: 0x0000AA64 File Offset: 0x00008C64
            [__DynamicallyInvokable]
            public bool IsProperSupersetOf(IEnumerable<T> other)
            {
                if (other == null)
                {
                    throw new ArgumentNullException("other");
                }
                if (this.m_count == 0)
                {
                    return false;
                }
                ICollection<T> collection = other as ICollection<T>;
                if (collection != null)
                {
                    if (collection.Count == 0)
                    {
                        return true;
                    }
                    HashSet<T> hashSet = other as HashSet<T>;
                    if (hashSet != null && HashSet<T>.AreEqualityComparersEqual(this, hashSet))
                    {
                        return hashSet.Count < this.m_count && this.ContainsAllElements(hashSet);
                    }
                }
                HashSet<T>.ElementCount elementCount = this.CheckUniqueAndUnfoundElements(other, true);
                return elementCount.uniqueCount < this.m_count && elementCount.unfoundCount == 0;
            }
    
            /// <summary>Determines whether the current <see cref="T:System.Collections.Generic.HashSet`1" /> object and a specified collection share common elements.</summary>
            /// <param name="other">The collection to compare to the current <see cref="T:System.Collections.Generic.HashSet`1" /> object.</param>
            /// <returns>
            ///     <see langword="true" /> if the <see cref="T:System.Collections.Generic.HashSet`1" /> object and <paramref name="other" /> share at least one common element; otherwise, <see langword="false" />.</returns>
            /// <exception cref="T:System.ArgumentNullException">
            ///         <paramref name="other" /> is <see langword="null" />.</exception>
            // Token: 0x060003F7 RID: 1015 RVA: 0x0000AAEC File Offset: 0x00008CEC
            [__DynamicallyInvokable]
            public bool Overlaps(IEnumerable<T> other)
            {
                if (other == null)
                {
                    throw new ArgumentNullException("other");
                }
                if (this.m_count == 0)
                {
                    return false;
                }
                foreach (T item in other)
                {
                    if (this.Contains(item))
                    {
                        return true;
                    }
                }
                return false;
            }
    
            /// <summary>Determines whether a <see cref="T:System.Collections.Generic.HashSet`1" /> object and the specified collection contain the same elements.</summary>
            /// <param name="other">The collection to compare to the current <see cref="T:System.Collections.Generic.HashSet`1" /> object.</param>
            /// <returns>
            ///     <see langword="true" /> if the <see cref="T:System.Collections.Generic.HashSet`1" /> object is equal to <paramref name="other" />; otherwise, false.</returns>
            /// <exception cref="T:System.ArgumentNullException">
            ///         <paramref name="other" /> is <see langword="null" />.</exception>
            // Token: 0x060003F8 RID: 1016 RVA: 0x0000AB58 File Offset: 0x00008D58
            [__DynamicallyInvokable]
            public bool SetEquals(IEnumerable<T> other)
            {
                if (other == null)
                {
                    throw new ArgumentNullException("other");
                }
                HashSet<T> hashSet = other as HashSet<T>;
                if (hashSet != null && HashSet<T>.AreEqualityComparersEqual(this, hashSet))
                {
                    return this.m_count == hashSet.Count && this.ContainsAllElements(hashSet);
                }
                ICollection<T> collection = other as ICollection<T>;
                if (collection != null && this.m_count == 0 && collection.Count > 0)
                {
                    return false;
                }
                HashSet<T>.ElementCount elementCount = this.CheckUniqueAndUnfoundElements(other, true);
                return elementCount.uniqueCount == this.m_count && elementCount.unfoundCount == 0;
            }
    
            /// <summary>Copies the elements of a <see cref="T:System.Collections.Generic.HashSet`1" /> object to an array.</summary>
            /// <param name="array">The one-dimensional array that is the destination of the elements copied from the <see cref="T:System.Collections.Generic.HashSet`1" /> object. The array must have zero-based indexing.</param>
            /// <exception cref="T:System.ArgumentNullException">
            ///         <paramref name="array" /> is <see langword="null" />.</exception>
            // Token: 0x060003F9 RID: 1017 RVA: 0x0000ABDD File Offset: 0x00008DDD
            [__DynamicallyInvokable]
            public void CopyTo(T[] array)
            {
                this.CopyTo(array, 0, this.m_count);
            }
    
            /// <summary>Copies the specified number of elements of a <see cref="T:System.Collections.Generic.HashSet`1" /> object to an array, starting at the specified array index.</summary>
            /// <param name="array">The one-dimensional array that is the destination of the elements copied from the <see cref="T:System.Collections.Generic.HashSet`1" /> object. The array must have zero-based indexing.</param>
            /// <param name="arrayIndex">The zero-based index in <paramref name="array" /> at which copying begins.</param>
            /// <param name="count">The number of elements to copy to <paramref name="array" />.</param>
            /// <exception cref="T:System.ArgumentNullException">
            ///         <paramref name="array" /> is <see langword="null" />.</exception>
            /// <exception cref="T:System.ArgumentOutOfRangeException">
            ///         <paramref name="arrayIndex" /> is less than 0.-or-
            ///         <paramref name="count" /> is less than 0.</exception>
            /// <exception cref="T:System.ArgumentException">
            ///         <paramref name="arrayIndex" /> is greater than the length of the destination <paramref name="array" />.-or-
            ///         <paramref name="count" /> is greater than the available space from the <paramref name="index" /> to the end of the destination <paramref name="array" />.</exception>
            // Token: 0x060003FA RID: 1018 RVA: 0x0000ABF0 File Offset: 0x00008DF0
            [__DynamicallyInvokable]
            public void CopyTo(T[] array, int arrayIndex, int count)
            {
                if (array == null)
                {
                    throw new ArgumentNullException("array");
                }
                if (arrayIndex < 0)
                {
                    throw new ArgumentOutOfRangeException("arrayIndex", SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
                }
                if (count < 0)
                {
                    throw new ArgumentOutOfRangeException("count", SR.GetString("ArgumentOutOfRange_NeedNonNegNum"));
                }
                if (arrayIndex > array.Length || count > array.Length - arrayIndex)
                {
                    throw new ArgumentException(SR.GetString("Arg_ArrayPlusOffTooSmall"));
                }
                int num = 0;
                int num2 = 0;
                while (num2 < this.m_lastIndex && num < count)
                {
                    if (this.m_slots[num2].hashCode >= 0)
                    {
                        array[arrayIndex + num] = this.m_slots[num2].value;
                        num++;
                    }
                    num2++;
                }
            }
    
            /// <summary>Removes all elements that match the conditions defined by the specified predicate from a <see cref="T:System.Collections.Generic.HashSet`1" /> collection.</summary>
            /// <param name="match">The <see cref="T:System.Predicate`1" /> delegate that defines the conditions of the elements to remove.</param>
            /// <returns>The number of elements that were removed from the <see cref="T:System.Collections.Generic.HashSet`1" /> collection.</returns>
            /// <exception cref="T:System.ArgumentNullException">
            ///         <paramref name="match" /> is <see langword="null" />.</exception>
            // Token: 0x060003FB RID: 1019 RVA: 0x0000ACA4 File Offset: 0x00008EA4
            [__DynamicallyInvokable]
            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 value = this.m_slots[i].value;
                        if (match(value) && this.Remove(value))
                        {
                            num++;
                        }
                    }
                }
                return num;
            }
    
            /// <summary>Gets the <see cref="T:System.Collections.Generic.IEqualityComparer`1" /> object that is used to determine equality for the values in the set.</summary>
            /// <returns>The <see cref="T:System.Collections.Generic.IEqualityComparer`1" /> object that is used to determine equality for the values in the set.</returns>
            // Token: 0x170000E5 RID: 229
            // (get) Token: 0x060003FC RID: 1020 RVA: 0x0000AD0F File Offset: 0x00008F0F
            [__DynamicallyInvokable]
            public IEqualityComparer<T> Comparer
            {
                [__DynamicallyInvokable]
                get
                {
                    return this.m_comparer;
                }
            }
    
            /// <summary>Sets the capacity of a <see cref="T:System.Collections.Generic.HashSet`1" /> object to the actual number of elements it contains, rounded up to a nearby, implementation-specific value.</summary>
            // Token: 0x060003FD RID: 1021 RVA: 0x0000AD18 File Offset: 0x00008F18
            [__DynamicallyInvokable]
            public void TrimExcess()
            {
                if (this.m_count == 0)
                {
                    this.m_buckets = null;
                    this.m_slots = null;
                    this.m_version++;
                    return;
                }
                int prime = HashHelpers.GetPrime(this.m_count);
                HashSet<T>.Slot[] array = new HashSet<T>.Slot[prime];
                int[] array2 = new int[prime];
                int num = 0;
                for (int i = 0; i < this.m_lastIndex; i++)
                {
                    if (this.m_slots[i].hashCode >= 0)
                    {
                        array[num] = this.m_slots[i];
                        int num2 = array[num].hashCode % prime;
                        array[num].next = array2[num2] - 1;
                        array2[num2] = num + 1;
                        num++;
                    }
                }
                this.m_lastIndex = num;
                this.m_slots = array;
                this.m_buckets = array2;
                this.m_freeList = -1;
            }
    
            /// <summary>Returns an <see cref="T:System.Collections.IEqualityComparer" /> object that can be used for equality testing of a <see cref="T:System.Collections.Generic.HashSet`1" /> object.</summary>
            /// <returns>An <see cref="T:System.Collections.IEqualityComparer" /> object that can be used for deep equality testing of the <see cref="T:System.Collections.Generic.HashSet`1" /> object.</returns>
            // Token: 0x060003FE RID: 1022 RVA: 0x0000ADED File Offset: 0x00008FED
            public static IEqualityComparer<HashSet<T>> CreateSetComparer()
            {
                return new HashSetEqualityComparer<T>();
            }
    
            // Token: 0x060003FF RID: 1023 RVA: 0x0000ADF4 File Offset: 0x00008FF4
            private void Initialize(int capacity)
            {
                int prime = HashHelpers.GetPrime(capacity);
                this.m_buckets = new int[prime];
                this.m_slots = new HashSet<T>.Slot[prime];
            }
    
            // Token: 0x06000400 RID: 1024 RVA: 0x0000AE20 File Offset: 0x00009020
            private void IncreaseCapacity()
            {
                int num = HashHelpers.ExpandPrime(this.m_count);
                if (num <= this.m_count)
                {
                    throw new ArgumentException(SR.GetString("Arg_HSCapacityOverflow"));
                }
                this.SetCapacity(num, false);
            }
    
            // Token: 0x06000401 RID: 1025 RVA: 0x0000AE5C File Offset: 0x0000905C
            private void SetCapacity(int newSize, bool forceNewHashCodes)
            {
                HashSet<T>.Slot[] array = new HashSet<T>.Slot[newSize];
                if (this.m_slots != null)
                {
                    Array.Copy(this.m_slots, 0, array, 0, this.m_lastIndex);
                }
                if (forceNewHashCodes)
                {
                    for (int i = 0; i < this.m_lastIndex; i++)
                    {
                        if (array[i].hashCode != -1)
                        {
                            array[i].hashCode = this.InternalGetHashCode(array[i].value);
                        }
                    }
                }
                int[] array2 = new int[newSize];
                for (int j = 0; j < this.m_lastIndex; j++)
                {
                    int num = array[j].hashCode % newSize;
                    array[j].next = array2[num] - 1;
                    array2[num] = j + 1;
                }
                this.m_slots = array;
                this.m_buckets = array2;
            }
    
            // Token: 0x06000402 RID: 1026 RVA: 0x0000AF1C File Offset: 0x0000911C
            private bool AddIfNotPresent(T value)
            {
                if (this.m_buckets == null)
                {
                    this.Initialize(0);
                }
                int num = this.InternalGetHashCode(value);
                int num2 = num % this.m_buckets.Length;
                int num3 = 0;
                for (int i = this.m_buckets[num % this.m_buckets.Length] - 1; i >= 0; i = this.m_slots[i].next)
                {
                    if (this.m_slots[i].hashCode == num && this.m_comparer.Equals(this.m_slots[i].value, value))
                    {
                        return false;
                    }
                    num3++;
                }
                int num4;
                if (this.m_freeList >= 0)
                {
                    num4 = this.m_freeList;
                    this.m_freeList = this.m_slots[num4].next;
                }
                else
                {
                    if (this.m_lastIndex == this.m_slots.Length)
                    {
                        this.IncreaseCapacity();
                        num2 = num % this.m_buckets.Length;
                    }
                    num4 = this.m_lastIndex;
                    this.m_lastIndex++;
                }
                this.m_slots[num4].hashCode = num;
                this.m_slots[num4].value = value;
                this.m_slots[num4].next = this.m_buckets[num2] - 1;
                this.m_buckets[num2] = num4 + 1;
                this.m_count++;
                this.m_version++;
                if (num3 > 100 && HashHelpers.IsWellKnownEqualityComparer(this.m_comparer))
                {
                    this.m_comparer = (IEqualityComparer<T>)HashHelpers.GetRandomizedEqualityComparer(this.m_comparer);
                    this.SetCapacity(this.m_buckets.Length, true);
                }
                return true;
            }
    
            // Token: 0x06000403 RID: 1027 RVA: 0x0000B0B8 File Offset: 0x000092B8
            private void AddValue(int index, int hashCode, T value)
            {
                int num = hashCode % this.m_buckets.Length;
                this.m_slots[index].hashCode = hashCode;
                this.m_slots[index].value = value;
                this.m_slots[index].next = this.m_buckets[num] - 1;
                this.m_buckets[num] = index + 1;
            }
    
            // Token: 0x06000404 RID: 1028 RVA: 0x0000B11C File Offset: 0x0000931C
            private bool ContainsAllElements(IEnumerable<T> other)
            {
                foreach (T item in other)
                {
                    if (!this.Contains(item))
                    {
                        return false;
                    }
                }
                return true;
            }
    
            // Token: 0x06000405 RID: 1029 RVA: 0x0000B170 File Offset: 0x00009370
            private bool IsSubsetOfHashSetWithSameEC(HashSet<T> other)
            {
                foreach (T item in this)
                {
                    if (!other.Contains(item))
                    {
                        return false;
                    }
                }
                return true;
            }
    
            // Token: 0x06000406 RID: 1030 RVA: 0x0000B1C8 File Offset: 0x000093C8
            private void IntersectWithHashSetWithSameEC(HashSet<T> other)
            {
                for (int i = 0; i < this.m_lastIndex; i++)
                {
                    if (this.m_slots[i].hashCode >= 0)
                    {
                        T value = this.m_slots[i].value;
                        if (!other.Contains(value))
                        {
                            this.Remove(value);
                        }
                    }
                }
            }
    
            // Token: 0x06000407 RID: 1031 RVA: 0x0000B220 File Offset: 0x00009420
            [SecuritySafeCritical]
            private unsafe void IntersectWithEnumerable(IEnumerable<T> other)
            {
                int lastIndex = this.m_lastIndex;
                int num = BitHelper.ToIntArrayLength(lastIndex);
                BitHelper bitHelper;
                if (num <= 100)
                {
                    int* bitArrayPtr = stackalloc int[checked(unchecked((UIntPtr)num) * 4)];
                    bitHelper = new BitHelper(bitArrayPtr, num);
                }
                else
                {
                    int[] bitArray = new int[num];
                    bitHelper = new BitHelper(bitArray, num);
                }
                foreach (T item in other)
                {
                    int num2 = this.InternalIndexOf(item);
                    if (num2 >= 0)
                    {
                        bitHelper.MarkBit(num2);
                    }
                }
                for (int i = 0; i < lastIndex; i++)
                {
                    if (this.m_slots[i].hashCode >= 0 && !bitHelper.IsMarked(i))
                    {
                        this.Remove(this.m_slots[i].value);
                    }
                }
            }
    
            // Token: 0x06000408 RID: 1032 RVA: 0x0000B2FC File Offset: 0x000094FC
            private int InternalIndexOf(T item)
            {
                int num = this.InternalGetHashCode(item);
                for (int i = this.m_buckets[num % this.m_buckets.Length] - 1; i >= 0; i = this.m_slots[i].next)
                {
                    if (this.m_slots[i].hashCode == num && this.m_comparer.Equals(this.m_slots[i].value, item))
                    {
                        return i;
                    }
                }
                return -1;
            }
    
            // Token: 0x06000409 RID: 1033 RVA: 0x0000B374 File Offset: 0x00009574
            private void SymmetricExceptWithUniqueHashSet(HashSet<T> other)
            {
                foreach (T t in other)
                {
                    if (!this.Remove(t))
                    {
                        this.AddIfNotPresent(t);
                    }
                }
            }
    
            // Token: 0x0600040A RID: 1034 RVA: 0x0000B3CC File Offset: 0x000095CC
            [SecuritySafeCritical]
            private unsafe void SymmetricExceptWithEnumerable(IEnumerable<T> other)
            {
                int lastIndex = this.m_lastIndex;
                int num = BitHelper.ToIntArrayLength(lastIndex);
                BitHelper bitHelper;
                checked
                {
                    BitHelper bitHelper2;
                    if (num <= 50)
                    {
                        int* bitArrayPtr = stackalloc int[unchecked((UIntPtr)num) * 4];
                        bitHelper = new BitHelper(bitArrayPtr, num);
                        int* bitArrayPtr2 = stackalloc int[unchecked((UIntPtr)num) * 4];
                        bitHelper2 = new BitHelper(bitArrayPtr2, num);
                    }
                    else
                    {
                        int[] bitArray = new int[num];
                        bitHelper = new BitHelper(bitArray, num);
                        int[] bitArray2 = new int[num];
                        bitHelper2 = new BitHelper(bitArray2, num);
                    }
                    foreach (T value in other)
                    {
                        int num2 = 0;
                        bool flag = this.AddOrGetLocation(value, out num2);
                        if (flag)
                        {
                            bitHelper2.MarkBit(num2);
                        }
                        else if (num2 < lastIndex && !bitHelper2.IsMarked(num2))
                        {
                            bitHelper.MarkBit(num2);
                        }
                    }
                }
                for (int i = 0; i < lastIndex; i++)
                {
                    if (bitHelper.IsMarked(i))
                    {
                        this.Remove(this.m_slots[i].value);
                    }
                }
            }
    
            // Token: 0x0600040B RID: 1035 RVA: 0x0000B4D4 File Offset: 0x000096D4
            private bool AddOrGetLocation(T value, out int location)
            {
                int num = this.InternalGetHashCode(value);
                int num2 = num % this.m_buckets.Length;
                for (int i = this.m_buckets[num % this.m_buckets.Length] - 1; i >= 0; i = this.m_slots[i].next)
                {
                    if (this.m_slots[i].hashCode == num && this.m_comparer.Equals(this.m_slots[i].value, value))
                    {
                        location = i;
                        return false;
                    }
                }
                int num3;
                if (this.m_freeList >= 0)
                {
                    num3 = this.m_freeList;
                    this.m_freeList = this.m_slots[num3].next;
                }
                else
                {
                    if (this.m_lastIndex == this.m_slots.Length)
                    {
                        this.IncreaseCapacity();
                        num2 = num % this.m_buckets.Length;
                    }
                    num3 = this.m_lastIndex;
                    this.m_lastIndex++;
                }
                this.m_slots[num3].hashCode = num;
                this.m_slots[num3].value = value;
                this.m_slots[num3].next = this.m_buckets[num2] - 1;
                this.m_buckets[num2] = num3 + 1;
                this.m_count++;
                this.m_version++;
                location = num3;
                return true;
            }
    
            // Token: 0x0600040C RID: 1036 RVA: 0x0000B624 File Offset: 0x00009824
            [SecuritySafeCritical]
            private unsafe HashSet<T>.ElementCount CheckUniqueAndUnfoundElements(IEnumerable<T> other, bool returnIfUnfound)
            {
                HashSet<T>.ElementCount result;
                if (this.m_count == 0)
                {
                    int num = 0;
                    using (IEnumerator<T> enumerator = other.GetEnumerator())
                    {
                        if (enumerator.MoveNext())
                        {
                            T t = enumerator.Current;
                            num++;
                        }
                    }
                    result.uniqueCount = 0;
                    result.unfoundCount = num;
                    return result;
                }
                int lastIndex = this.m_lastIndex;
                int num2 = BitHelper.ToIntArrayLength(lastIndex);
                BitHelper bitHelper;
                if (num2 <= 100)
                {
                    int* bitArrayPtr = stackalloc int[checked(unchecked((UIntPtr)num2) * 4)];
                    bitHelper = new BitHelper(bitArrayPtr, num2);
                }
                else
                {
                    int[] bitArray = new int[num2];
                    bitHelper = new BitHelper(bitArray, num2);
                }
                int num3 = 0;
                int num4 = 0;
                foreach (T item in other)
                {
                    int num5 = this.InternalIndexOf(item);
                    if (num5 >= 0)
                    {
                        if (!bitHelper.IsMarked(num5))
                        {
                            bitHelper.MarkBit(num5);
                            num4++;
                        }
                    }
                    else
                    {
                        num3++;
                        if (returnIfUnfound)
                        {
                            break;
                        }
                    }
                }
                result.uniqueCount = num4;
                result.unfoundCount = num3;
                return result;
            }
    
            // Token: 0x0600040D RID: 1037 RVA: 0x0000B74C File Offset: 0x0000994C
            internal T[] ToArray()
            {
                T[] array = new T[this.Count];
                this.CopyTo(array);
                return array;
            }
    
            // Token: 0x0600040E RID: 1038 RVA: 0x0000B770 File Offset: 0x00009970
            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))
                {
                    foreach (T x in set2)
                    {
                        bool flag = false;
                        foreach (T y in set1)
                        {
                            if (comparer.Equals(x, y))
                            {
                                flag = true;
                                break;
                            }
                        }
                        if (!flag)
                        {
                            return false;
                        }
                    }
                    return true;
                }
                if (set1.Count != set2.Count)
                {
                    return false;
                }
                foreach (T item in set2)
                {
                    if (!set1.Contains(item))
                    {
                        return false;
                    }
                }
                return true;
            }
    
            // Token: 0x0600040F RID: 1039 RVA: 0x0000B880 File Offset: 0x00009A80
            private static bool AreEqualityComparersEqual(HashSet<T> set1, HashSet<T> set2)
            {
                return set1.Comparer.Equals(set2.Comparer);
            }
    
            // Token: 0x06000410 RID: 1040 RVA: 0x0000B893 File Offset: 0x00009A93
            private int InternalGetHashCode(T item)
            {
                if (item == null)
                {
                    return 0;
                }
                return this.m_comparer.GetHashCode(item) & int.MaxValue;
            }
    
            // Token: 0x040004CB RID: 1227
            private const int Lower31BitMask = 2147483647;
    
            // Token: 0x040004CC RID: 1228
            private const int StackAllocThreshold = 100;
    
            // Token: 0x040004CD RID: 1229
            private const int ShrinkThreshold = 3;
    
            // Token: 0x040004CE RID: 1230
            private const string CapacityName = "Capacity";
    
            // Token: 0x040004CF RID: 1231
            private const string ElementsName = "Elements";
    
            // Token: 0x040004D0 RID: 1232
            private const string ComparerName = "Comparer";
    
            // Token: 0x040004D1 RID: 1233
            private const string VersionName = "Version";
    
            // Token: 0x040004D2 RID: 1234
            private int[] m_buckets;
    
            // Token: 0x040004D3 RID: 1235
            private HashSet<T>.Slot[] m_slots;
    
            // Token: 0x040004D4 RID: 1236
            private int m_count;
    
            // Token: 0x040004D5 RID: 1237
            private int m_lastIndex;
    
            // Token: 0x040004D6 RID: 1238
            private int m_freeList;
    
            // Token: 0x040004D7 RID: 1239
            private IEqualityComparer<T> m_comparer;
    
            // Token: 0x040004D8 RID: 1240
            private int m_version;
    
            // Token: 0x040004D9 RID: 1241
            private SerializationInfo m_siInfo;
    
            // Token: 0x02000306 RID: 774
            internal struct ElementCount
            {
                // Token: 0x04000E1F RID: 3615
                internal int uniqueCount;
    
                // Token: 0x04000E20 RID: 3616
                internal int unfoundCount;
            }
    
            // Token: 0x02000307 RID: 775
            internal struct Slot
            {
                // Token: 0x04000E21 RID: 3617
                internal int hashCode;
    
                // Token: 0x04000E22 RID: 3618
                internal int next;
    
                // Token: 0x04000E23 RID: 3619
                internal T value;
            }
    
            /// <summary>Enumerates the elements of a <see cref="T:System.Collections.Generic.HashSet`1" /> object.</summary>
            // Token: 0x02000308 RID: 776
            [__DynamicallyInvokable]
            [HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]
            [Serializable]
            public struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator
            {
                // Token: 0x06001A7C RID: 6780 RVA: 0x00060EE1 File Offset: 0x0005F0E1
                internal Enumerator(HashSet<T> set)
                {
                    this.set = set;
                    this.index = 0;
                    this.version = set.m_version;
                    this.current = default(T);
                }
    
                /// <summary>Releases all resources used by a <see cref="T:System.Collections.Generic.HashSet`1.Enumerator" /> object.</summary>
                // Token: 0x06001A7D RID: 6781 RVA: 0x00060F09 File Offset: 0x0005F109
                [__DynamicallyInvokable]
                public void Dispose()
                {
                }
    
                /// <summary>Advances the enumerator to the next element of the <see cref="T:System.Collections.Generic.HashSet`1" /> collection.</summary>
                /// <returns>
                ///     <see langword="true" /> if the enumerator was successfully advanced to the next element; <see langword="false" /> if the enumerator has passed the end of the collection.</returns>
                /// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created. </exception>
                // Token: 0x06001A7E RID: 6782 RVA: 0x00060F0C File Offset: 0x0005F10C
                [__DynamicallyInvokable]
                public bool MoveNext()
                {
                    if (this.version != this.set.m_version)
                    {
                        throw new InvalidOperationException(SR.GetString("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;
                }
    
                /// <summary>Gets the element at the current position of the enumerator.</summary>
                /// <returns>The element in the <see cref="T:System.Collections.Generic.HashSet`1" /> collection at the current position of the enumerator.</returns>
                // Token: 0x170004ED RID: 1261
                // (get) Token: 0x06001A7F RID: 6783 RVA: 0x00060FCC File Offset: 0x0005F1CC
                [__DynamicallyInvokable]
                public T Current
                {
                    [__DynamicallyInvokable]
                    get
                    {
                        return this.current;
                    }
                }
    
                /// <summary>Gets the element at the current position of the enumerator.</summary>
                /// <returns>The element in the collection at the current position of the enumerator, as an <see cref="T:System.Object" />.</returns>
                /// <exception cref="T:System.InvalidOperationException">The enumerator is positioned before the first element of the collection or after the last element. </exception>
                // Token: 0x170004EE RID: 1262
                // (get) Token: 0x06001A80 RID: 6784 RVA: 0x00060FD4 File Offset: 0x0005F1D4
                [__DynamicallyInvokable]
                object IEnumerator.Current
                {
                    [__DynamicallyInvokable]
                    get
                    {
                        if (this.index == 0 || this.index == this.set.m_lastIndex + 1)
                        {
                            throw new InvalidOperationException(SR.GetString("InvalidOperation_EnumOpCantHappen"));
                        }
                        return this.Current;
                    }
                }
    
                /// <summary>Sets the enumerator to its initial position, which is before the first element in the collection.</summary>
                /// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created. </exception>
                // Token: 0x06001A81 RID: 6785 RVA: 0x0006100E File Offset: 0x0005F20E
                [__DynamicallyInvokable]
                void IEnumerator.Reset()
                {
                    if (this.version != this.set.m_version)
                    {
                        throw new InvalidOperationException(SR.GetString("InvalidOperation_EnumFailedVersion"));
                    }
                    this.index = 0;
                    this.current = default(T);
                }
    
                // Token: 0x04000E24 RID: 3620
                private HashSet<T> set;
    
                // Token: 0x04000E25 RID: 3621
                private int index;
    
                // Token: 0x04000E26 RID: 3622
                private int version;
    
                // Token: 0x04000E27 RID: 3623
                private T current;
            }
        }
    }
    
    

    相关文章

      网友评论

        本文标题:C#HashSet源码

        本文链接:https://www.haomeiwen.com/subject/uqvlpdtx.html