diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs index 902e9168872cf4..23e9fc35e59b2a 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableSortedSet_1.cs @@ -375,24 +375,55 @@ public bool SetEquals(IEnumerable other) return true; } - var otherSet = new SortedSet(other, this.KeyComparer); - if (this.Count != otherSet.Count) + switch (other) { - return false; + case ImmutableSortedSet otherAsImmutableSortedSet: + if (otherAsImmutableSortedSet.Count != this.Count) + { + return false; + } + + if (EqualityComparer>.Default.Equals(this.KeyComparer, otherAsImmutableSortedSet.KeyComparer)) + { + return SetEqualsWithImmutableSortedSet(otherAsImmutableSortedSet, this); + } + break; + + case SortedSet otherAsSortedSet: + if (otherAsSortedSet.Count != this.Count) + { + return false; + } + + if (EqualityComparer>.Default.Equals(this.KeyComparer, otherAsSortedSet.Comparer)) + { + return SetEqualsWithSortedSet(otherAsSortedSet, this); + } + break; + + case ICollection otherAsICollectionGeneric: + // We check for < instead of != because other is not guaranteed to be a set; it could be a collection with duplicates. + if (otherAsICollectionGeneric.Count < this.Count) + { + return false; + } + break; + + case ICollection otherAsICollection: + if (otherAsICollection.Count < this.Count) + { + return false; + } + break; } - int matches = 0; - foreach (T item in otherSet) + var otherSet = new SortedSet(other, this.KeyComparer); + if (otherSet.Count != this.Count) { - if (!this.Contains(item)) - { - return false; - } - - matches++; + return false; } - return matches == this.Count; + return SetEqualsWithSortedSet(otherSet, this); } /// @@ -1016,6 +1047,42 @@ private static bool TryCastToImmutableSortedSet(IEnumerable sequence, [NotNul return false; } + private static bool SetEqualsWithImmutableSortedSet(ImmutableSortedSet other, ImmutableSortedSet source) + { + // We can use a linear scan because both sets are sorted using the same comparer. + using var e = other.GetEnumerator(); + foreach (T item in source) + { + bool eHasMore = e.MoveNext(); + Debug.Assert(eHasMore); + + if (source.KeyComparer.Compare(item, e.Current) != 0) + { + return false; + } + } + + return true; + } + + private static bool SetEqualsWithSortedSet(SortedSet other, ImmutableSortedSet source) + { + // We can use a linear scan because both sets are sorted using the same comparer. + using var e = other.GetEnumerator(); + foreach (T item in source) + { + bool eHasMore = e.MoveNext(); + Debug.Assert(eHasMore); + + if (source.KeyComparer.Compare(item, e.Current) != 0) + { + return false; + } + } + + return true; + } + /// /// Creates a new sorted set wrapper for a node tree. ///