From a4fd21618635b891fefe34d5e440d6d9464e659f Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Wed, 7 Sep 2022 09:38:29 +0100 Subject: [PATCH] Retain existing array in RepeatedField.Clear Fixes #7828. (Also tweaks the comment for Capacity.) --- .../Collections/RepeatedFieldTest.cs | 12 ++++++++++++ .../src/Google.Protobuf/Collections/RepeatedField.cs | 10 +++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs b/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs index 766b4cb5db7a8..5a8977d611cba 100644 --- a/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs +++ b/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs @@ -888,5 +888,17 @@ public void Capacity_Zero() Assert.DoesNotThrow(() => list.Capacity = 0, "Can set Capacity to 0"); Assert.AreEqual(0, list.Capacity); } + + [Test] + public void Clear_CapacityUnaffected() + { + var list = new RepeatedField { 1 }; + Assert.AreEqual(1, list.Count); + Assert.AreEqual(8, list.Capacity); + + list.Clear(); + Assert.AreEqual(0, list.Count); + Assert.AreEqual(8, list.Capacity); + } } } diff --git a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs index 832e1669430eb..56117fd325d98 100644 --- a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs +++ b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs @@ -279,8 +279,9 @@ public void WriteTo(ref WriteContext ctx, FieldCodec codec) } /// - /// Gets and sets the capacity of the RepeatedField's internal array. WHen set, the internal array is reallocated to the given capacity. - /// The new value is less than Count -or- when Count is less than 0. + /// Gets and sets the capacity of the RepeatedField's internal array. + /// When set, the internal array is reallocated to the given capacity. + /// The new value is less than . /// public int Capacity { @@ -338,7 +339,10 @@ public void Add(T item) /// public void Clear() { - array = EmptyArray; + // Clear the content of the array (so that any objects it referred to can be garbage collected) + // but keep the capacity the same. This allows large repeated fields to be reused without + // array reallocation. + Array.Clear(array, 0, count); count = 0; }