From ec280c90b0d43209f493c03c25f395f8042268aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Cant=C3=BA?= Date: Tue, 23 Apr 2024 18:19:20 -0500 Subject: [PATCH] Add implicit operator ROS for StringValues --- .../ref/Microsoft.Extensions.Primitives.cs | 5 +++ .../src/StringValues.cs | 20 ++++++++++ .../tests/StringValuesTests.cs | 37 +++++++++++++++++++ 3 files changed, 62 insertions(+) diff --git a/src/libraries/Microsoft.Extensions.Primitives/ref/Microsoft.Extensions.Primitives.cs b/src/libraries/Microsoft.Extensions.Primitives/ref/Microsoft.Extensions.Primitives.cs index a5f5f188981cd6..114ccc94e4552c 100644 --- a/src/libraries/Microsoft.Extensions.Primitives/ref/Microsoft.Extensions.Primitives.cs +++ b/src/libraries/Microsoft.Extensions.Primitives/ref/Microsoft.Extensions.Primitives.cs @@ -167,6 +167,11 @@ public void Reset() { } public static bool operator ==(string?[]? left, Microsoft.Extensions.Primitives.StringValues right) { throw null; } public static implicit operator string?(Microsoft.Extensions.Primitives.StringValues values) { throw null; } public static implicit operator string?[]?(Microsoft.Extensions.Primitives.StringValues value) { throw null; } +#if NET9_0_OR_GREATER +#pragma warning disable CS3006 // Overloaded method 'StringValues.implicit operator ReadOnlySpan(in StringValues)' differing only in ref or out, or in array rank, is not CLS-compliant. + public static implicit operator System.ReadOnlySpan (in Microsoft.Extensions.Primitives.StringValues value) { throw null; } +#pragma warning restore CS3006 +#endif public static implicit operator Microsoft.Extensions.Primitives.StringValues(string? value) { throw null; } public static implicit operator Microsoft.Extensions.Primitives.StringValues(string?[]? values) { throw null; } public static bool operator !=(Microsoft.Extensions.Primitives.StringValues left, Microsoft.Extensions.Primitives.StringValues right) { throw null; } diff --git a/src/libraries/Microsoft.Extensions.Primitives/src/StringValues.cs b/src/libraries/Microsoft.Extensions.Primitives/src/StringValues.cs index 45cfea152227dc..6878d45d035706 100644 --- a/src/libraries/Microsoft.Extensions.Primitives/src/StringValues.cs +++ b/src/libraries/Microsoft.Extensions.Primitives/src/StringValues.cs @@ -85,6 +85,26 @@ public static implicit operator StringValues(string?[]? values) return value.GetArrayValue(); } +#if NET9_0_OR_GREATER + /// + /// Defines an implicit conversion of a given to a string span. + /// + /// A to implicitly convert. +#pragma warning disable CS3006 // Overloaded method 'StringValues.implicit operator ReadOnlySpan(in StringValues)' differing only in ref or out, or in array rank, is not CLS-compliant. + public static implicit operator ReadOnlySpan(in StringValues value) +#pragma warning restore CS3006 + { + if (value._values is string) + { + return new ReadOnlySpan(in Unsafe.As(ref Unsafe.AsRef(in value._values))); + } + else + { + return new ReadOnlySpan((string?[]?)value._values); + } + } +#endif + /// /// Gets the number of elements contained in this . /// diff --git a/src/libraries/Microsoft.Extensions.Primitives/tests/StringValuesTests.cs b/src/libraries/Microsoft.Extensions.Primitives/tests/StringValuesTests.cs index 5a0a0719ccc574..32be480cf2150d 100644 --- a/src/libraries/Microsoft.Extensions.Primitives/tests/StringValuesTests.cs +++ b/src/libraries/Microsoft.Extensions.Primitives/tests/StringValuesTests.cs @@ -275,6 +275,43 @@ public void ImplicitStringArrayConverter_Works() Assert.Equal(aStringArray, stringValues); } +#if NETCOREAPP + [Fact] + public void ImplicitReadOnlySpanStringConverter_Works() + { + // from null string + StringValues stringValues = (string)null; + ReadOnlySpan span = (ReadOnlySpan)stringValues; + Assert.True(span.IsEmpty); + Assert.Equal((string[])stringValues, span); + + // from null string[] + stringValues = (string[])null; + span = (ReadOnlySpan)stringValues; + Assert.True(span.IsEmpty); + Assert.Equal((string[])stringValues, span); + + // from string + string aString = "abc"; + stringValues = (string)aString; + span = (ReadOnlySpan)stringValues; + Assert.Equal(1, span.Length); + Assert.Equal(aString, span[0]); + Assert.Equal((string[])stringValues, span); + + // from string[] + string bString = "bcd"; + string[] aStringArray = new[] { aString, bString }; + stringValues = (string[])aStringArray; + span = (ReadOnlySpan)stringValues; + Assert.Equal(2, span.Length); + Assert.Equal(aString, span[0]); + Assert.Equal(bString, span[1]); + Assert.Equal(aStringArray, span); + Assert.Equal((string[])stringValues, span); + } +#endif + [Theory] [MemberData(nameof(DefaultOrNullStringValues))] [MemberData(nameof(EmptyStringValues))]