diff --git a/Containers.Test/ContiguousSetTests.cs b/Containers.Test/ContiguousSetTests.cs index 321ff2f..c7250fd 100644 --- a/Containers.Test/ContiguousSetTests.cs +++ b/Containers.Test/ContiguousSetTests.cs @@ -297,6 +297,16 @@ public void ExceptWith_RemovesCommonElements() Assert.DoesNotContain(4, set1); } + [TestMethod] + public void ExceptWith_Self_EmptiesSet() + { + ContiguousSet set = [.. new int[] { 1, 2, 3, 4 }]; + + set.ExceptWith(set); + + Assert.IsEmpty(set); + } + [TestMethod] public void SymmetricExceptWith_KeepsUniqueElements() { diff --git a/Containers.Test/InsertionOrderSetTests.cs b/Containers.Test/InsertionOrderSetTests.cs index 7e198bc..313ef5f 100644 --- a/Containers.Test/InsertionOrderSetTests.cs +++ b/Containers.Test/InsertionOrderSetTests.cs @@ -310,6 +310,16 @@ public void ExceptWith_RemovesCommonElements() Assert.AreEqual(3, set1.ElementAt(1)); } + [TestMethod] + public void ExceptWith_Self_EmptiesSet() + { + InsertionOrderSet set = [.. new int[] { 1, 2, 3, 4 }]; + + set.ExceptWith(set); + + Assert.IsEmpty(set); + } + [TestMethod] public void WorksWithStrings_MaintainsInsertionOrder() { diff --git a/Containers.Test/OrderedSetTests.cs b/Containers.Test/OrderedSetTests.cs index 0610cec..c49465d 100644 --- a/Containers.Test/OrderedSetTests.cs +++ b/Containers.Test/OrderedSetTests.cs @@ -373,6 +373,16 @@ public void ExceptWith_RemovesSpecifiedElements() Assert.AreSequenceEqual(expected, set1); } + [TestMethod] + public void ExceptWith_Self_EmptiesSet() + { + OrderedSet set = [.. new int[] { 1, 2, 3, 4 }]; + + set.ExceptWith(set); + + Assert.IsEmpty(set); + } + [TestMethod] public void ExceptWith_NullCollection_ThrowsArgumentNullException() { diff --git a/Containers/ContiguousSet.cs b/Containers/ContiguousSet.cs index bc60ff1..c6c56fb 100644 --- a/Containers/ContiguousSet.cs +++ b/Containers/ContiguousSet.cs @@ -371,6 +371,13 @@ public void ExceptWith(IEnumerable other) { Ensure.NotNull(other); + // Removing while enumerating this set would skip or throw; excepting a set from itself empties it + if (ReferenceEquals(other, this)) + { + Clear(); + return; + } + foreach (T item in other) { Remove(item); diff --git a/Containers/InsertionOrderSet.cs b/Containers/InsertionOrderSet.cs index 9b92842..85ec45c 100644 --- a/Containers/InsertionOrderSet.cs +++ b/Containers/InsertionOrderSet.cs @@ -300,6 +300,13 @@ public void ExceptWith(IEnumerable other) { Ensure.NotNull(other); + // Removing while enumerating this set would skip or throw; excepting a set from itself empties it + if (ReferenceEquals(other, this)) + { + Clear(); + return; + } + foreach (T item in other) { Remove(item); diff --git a/Containers/OrderedSet.cs b/Containers/OrderedSet.cs index dd584c9..62de21d 100644 --- a/Containers/OrderedSet.cs +++ b/Containers/OrderedSet.cs @@ -381,6 +381,13 @@ public void ExceptWith(IEnumerable other) { Ensure.NotNull(other); + // Removing while enumerating this set would skip or throw; excepting a set from itself empties it + if (ReferenceEquals(other, this)) + { + Clear(); + return; + } + foreach (T item in other) { Remove(item);