From f8c3ab0f379ecd76009d5b06500be4e6201d4d0e Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 23 Sep 2026 18:30:37 +0000 Subject: [PATCH] fix: let OrderedCollection.GetRange take a zero-length range at the end [patch] GetRange guarded startIndex with ThrowIfGreaterThanOrEqual(startIndex, Count), which rejects startIndex == Count. That made a zero-length range at the end of the collection impossible to request, and made GetRange unusable on an empty collection at all, even though count == 0 makes both requests valid. List.GetRange explicitly allows index == Count when count == 0, and the sibling collections in this repo already agree: InsertionOrderCollection and ContiguousCollection check only startIndex >= 0, count >= 0 and startIndex + count <= Count. OrderedCollection was the only one with the extra check. Drop it and rely on the remaining three guards, which still reject every genuinely out-of-range request - including GetRange(3, 1) on a 3-element collection, via startIndex + count > Count. Adds three tests. Two fail before the change: - GetRange_ZeroCountAtEnd_ReturnsEmpty - GetRange_ZeroCountOnEmptyCollection_ReturnsEmpty and GetRange_ZeroCountMidCollection_ReturnsEmpty guards the case that already worked. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01T1ntzPwg732TrH7D5vWpSV --- Containers.Test/OrderedCollectionTests.cs | 39 +++++++++++++++++++++++ Containers/OrderedCollection.cs | 5 ++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/Containers.Test/OrderedCollectionTests.cs b/Containers.Test/OrderedCollectionTests.cs index e8cb56f..d4c5065 100644 --- a/Containers.Test/OrderedCollectionTests.cs +++ b/Containers.Test/OrderedCollectionTests.cs @@ -471,6 +471,45 @@ public void GetRange_ValidRange_ReturnsCorrectSubset() Assert.AreEqual(6, range[3]); } + [TestMethod] + public void GetRange_ZeroCountAtEnd_ReturnsEmpty() + { + // Arrange + OrderedCollection collection = new([1, 2, 3]); + + // Act: startIndex == Count is valid when count is zero, as it is for List.GetRange + OrderedCollection range = collection.GetRange(collection.Count, 0); + + // Assert + Assert.AreEqual(0, range.Count); + } + + [TestMethod] + public void GetRange_ZeroCountOnEmptyCollection_ReturnsEmpty() + { + // Arrange + OrderedCollection collection = []; + + // Act: the only range an empty collection has is the empty one at index 0 + OrderedCollection range = collection.GetRange(0, 0); + + // Assert + Assert.AreEqual(0, range.Count); + } + + [TestMethod] + public void GetRange_ZeroCountMidCollection_ReturnsEmpty() + { + // Arrange + OrderedCollection collection = new([1, 2, 3]); + + // Act + OrderedCollection range = collection.GetRange(1, 0); + + // Assert + Assert.AreEqual(0, range.Count); + } + [TestMethod] public void GetRange_InvalidStartIndex_ThrowsArgumentOutOfRangeException() { diff --git a/Containers/OrderedCollection.cs b/Containers/OrderedCollection.cs index 01faf2d..55d735d 100644 --- a/Containers/OrderedCollection.cs +++ b/Containers/OrderedCollection.cs @@ -345,11 +345,14 @@ public int IndexOf(T item) /// The zero-based starting index of the range. /// The number of elements in the range. /// A new OrderedCollection containing the elements in the specified range. + /// + /// As with , a equal to + /// is valid when is zero, and returns an empty collection. + /// /// Thrown when parameters are out of range. public OrderedCollection GetRange(int startIndex, int count) { ArgumentOutOfRangeException.ThrowIfNegative(startIndex); - ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual(startIndex, Count); ArgumentOutOfRangeException.ThrowIfNegative(count); ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex + count, Count);