diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Builder.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Builder.cs index 5d8dee3c2b8c85..5d414f4249796c 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Builder.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Builder.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Diagnostics; -using System.Runtime.CompilerServices; namespace System.Collections.Immutable { @@ -591,17 +590,10 @@ public void RemoveRange(int index, int length) if (index + length < this._count) { - -#if NET - if (RuntimeHelpers.IsReferenceOrContainsReferences()) - { - Array.Clear(_elements, index, length); // Clear the elements so that the gc can reclaim the references. - } -#endif Array.Copy(_elements, index + length, _elements, index, this.Count - index - length); } - this._count -= length; + this.Count -= length; } /// @@ -1095,7 +1087,7 @@ private void RemoveAtRange(ICollection indicesToRemove) Array.Copy(_elements, copied + removed, _elements, copied, _elements.Length - (copied + removed)); - _count -= indicesToRemove.Count; + this.Count -= indicesToRemove.Count; } /// Gets a for the filled portion of the backing array. diff --git a/src/libraries/System.Collections.Immutable/tests/ImmutableArrayBuilderTest.cs b/src/libraries/System.Collections.Immutable/tests/ImmutableArrayBuilderTest.cs index 079d7aebd3d928..0af58eff4a44b3 100644 --- a/src/libraries/System.Collections.Immutable/tests/ImmutableArrayBuilderTest.cs +++ b/src/libraries/System.Collections.Immutable/tests/ImmutableArrayBuilderTest.cs @@ -464,6 +464,69 @@ public void RemoveAll() AssertExtensions.Throws("match", () => builder.RemoveAll(match: null)); } + [Theory] + [InlineData(4, 0, 0)] + [InlineData(4, 4, 0)] + [InlineData(4, 0, 1)] + [InlineData(4, 1, 2)] + [InlineData(4, 3, 1)] + [InlineData(4, 0, 4)] + [InlineData(70, 0, 65)] + [InlineData(70, 1, 65)] + [InlineData(70, 5, 65)] + public void RemoveRange_ClearsElements(int count, int index, int length) + { + Verify(Enumerable.Range(1, count).ToArray()); + Verify(Enumerable.Range(1, count).Select(i => i.ToString()).ToArray()); + Verify(Enumerable.Range(1, count).Select(i => new KeyValuePair(i, i.ToString())).ToArray()); + + void Verify(T[] items) + { + T[] expected = items.Take(index).Concat(items.Skip(index + length)).ToArray(); + AssertRemovedElementsCleared(items, expected, builder => builder.RemoveRange(index, length)); + } + } + + [Theory] + [InlineData(0)] + [InlineData(1)] + [InlineData(4)] + [InlineData(70)] + public void RemoveAllAndEnumerableRemoveRange_ClearsElements(int count) + { + Verify(Enumerable.Range(1, count).ToArray()); + Verify(Enumerable.Range(1, count).Select(i => i.ToString()).ToArray()); + Verify(Enumerable.Range(1, count).Select(i => new KeyValuePair(i, i.ToString())).ToArray()); + + void Verify(T[] items) + { + foreach (T[] removed in new[] { Array.Empty(), items, items.Where((_, i) => i % 2 == 0).ToArray() }) + { + T[] expected = items.Where(item => !removed.Contains(item)).ToArray(); + AssertRemovedElementsCleared(items, expected, builder => builder.RemoveRange(removed)); + AssertRemovedElementsCleared(items, expected, builder => builder.RemoveRange(removed, EqualityComparer.Default)); + AssertRemovedElementsCleared(items, expected, builder => builder.RemoveAll(item => removed.Contains(item))); + } + } + } + + private static void AssertRemovedElementsCleared(T[] items, T[] expected, Action.Builder> remove) + { + foreach (int capacity in new[] { items.Length, items.Length + 8 }) + { + ImmutableArray.Builder builder = ImmutableArray.CreateBuilder(capacity); + builder.AddRange(items); + + remove(builder); + Assert.Equal(expected, builder); + + builder.Count = items.Length; + var expanded = new T[items.Length]; + Array.Copy(expected, expanded, expected.Length); + Assert.Equal(expanded, builder); + } + } + [Fact] public void ReverseContents() {