From 58b46d019568563e5bfc52a82560afaaa7a4bba4 Mon Sep 17 00:00:00 2001 From: Tristan Pratt Date: Sat, 17 Aug 2019 18:05:44 -0400 Subject: [PATCH] c# feature: new method AsSpan() on RepeatedField Provides very efficient access to the underlying data at the expense of foregoing null checks. --- .../Collections/RepeatedFieldTest.cs | 28 +++++++++++++++++++ .../Collections/RepeatedField.cs | 14 ++++++++++ 2 files changed, 42 insertions(+) diff --git a/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs b/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs index b3863a4965a1..5ed0147aafe6 100644 --- a/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs +++ b/csharp/src/Google.Protobuf.Test/Collections/RepeatedFieldTest.cs @@ -756,5 +756,33 @@ public void NaNValuesComparedBitwise() Assert.True(list1.Contains(SampleNaNs.SignallingFlipped)); Assert.False(list2.Contains(SampleNaNs.SignallingFlipped)); } + +#if NETCOREAPP2_1 + [Test] + public void AsSpan_BasicUsage() + { + var list = new RepeatedField { 10, 11 }; + var span = list.AsSpan(); + + // Span was constructed correctly + Assert.AreEqual(2, span.Length); + Assert.AreEqual(10, span[0]); + Assert.AreEqual(11, span[1]); + + // Writing to span writes to RepeatedField + span[0] = 100; + Assert.AreEqual(100, list[0]); + } + + [Test] + public void AsSpan_Empty() + { + var list = new RepeatedField(); + var span = list.AsSpan(); + + // Empty Span was constructed correctly + Assert.AreEqual(0, span.Length); + } +#endif } } diff --git a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs index 827bc711832b..c450bb0c85c1 100644 --- a/csharp/src/Google.Protobuf/Collections/RepeatedField.cs +++ b/csharp/src/Google.Protobuf/Collections/RepeatedField.cs @@ -543,6 +543,20 @@ public override string ToString() } } +#if NETSTANDARD2_0 + /// + /// Creates a new span over the RepeatedField. This is the most + /// efficient way to read and write values to the RepeatedField because + /// there are no internal null or bounds checks. You are responsible + /// for ensuring no null values are written to the span. + /// + /// Span representation of the RepeatedField + public Span AsSpan() + { + return array.AsSpan(0, count); + } +#endif + #region Explicit interface implementation for IList and ICollection. bool IList.IsFixedSize => false;