예제 #1
0
        // static Type isortedtype = typeof(ISorted<T>);

        /// <summary>
        /// Examine if collection1 and collection2 are equal as unsequenced collections
        /// using the specified item equalityComparer (assumed compatible with the two collections).
        /// </summary>
        /// <param name="collection1">The first collection</param>
        /// <param name="collection2">The second collection</param>
        /// <param name="itemequalityComparer">The item equalityComparer to use for comparison</param>
        /// <returns>True if equal</returns>
        public static bool StaticEquals(ICollection <T> collection1, ICollection <T> collection2, System.Collections.Generic.IEqualityComparer <T> itemequalityComparer)
        {
            if (object.ReferenceEquals(collection1, collection2))
            {
                return(true);
            }

            // bug20070227:
            if (collection1 == null || collection2 == null)
            {
                return(false);
            }

            if (collection1.Count != collection2.Count)
            {
                return(false);
            }

            //This way we might run through both enumerations twice, but
            //probably not (if the hash codes are good)
            //TODO: check equal equalityComparers, at least here!
            if (collection1.GetUnsequencedHashCode() != collection2.GetUnsequencedHashCode())
            {
                return(false);
            }

            //TODO: move this to the sorted implementation classes?
            //Really depends on speed of InstanceOfType: we could save a cast
            {
                if (collection1 is ISorted <T> stit && collection2 is ISorted <T> stat && stit.Comparer == stat.Comparer)
                {
                    using System.Collections.Generic.IEnumerator <T> dat = collection2.GetEnumerator(), dit = collection1.GetEnumerator();
                    while (dit.MoveNext())
                    {
                        dat.MoveNext();
                        if (!itemequalityComparer.Equals(dit.Current, dat.Current))
                        {
                            return(false);
                        }
                    }
                    return(true);
                }
            }

            if (!collection1.AllowsDuplicates && (collection2.AllowsDuplicates || collection2.ContainsSpeed >= collection1.ContainsSpeed))
            {
                foreach (T x in collection1)
                {
                    if (!collection2.Contains(x))
                    {
                        return(false);
                    }
                }
            }
            else if (!collection2.AllowsDuplicates)
            {
                foreach (T x in collection2)
                {
                    if (!collection1.Contains(x))
                    {
                        return(false);
                    }
                }
            }
            // Now tit.AllowsDuplicates && tat.AllowsDuplicates
            else if (collection1.DuplicatesByCounting && collection2.DuplicatesByCounting)
            {
                foreach (T item in collection2)
                {
                    if (collection1.ContainsCount(item) != collection2.ContainsCount(item))
                    {
                        return(false);
                    }
                }
            }
            else
            {
                // To avoid an O(n^2) algorithm, we make an aux hashtable to hold the count of items
                // bug20101103: HashDictionary<T, int> dict = new HashDictionary<T, int>();
                HashDictionary <T, int> dict = new HashDictionary <T, int>(itemequalityComparer);
                foreach (T item in collection2)
                {
                    int count = 1;
                    if (dict.FindOrAdd(item, ref count))
                    {
                        dict[item] = count + 1;
                    }
                }
                foreach (T item in collection1)
                {
                    var i = item;
                    if (dict.Find(ref i, out int count) && count > 0)
                    {
                        dict[item] = count - 1;
                    }