-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add implicit operator ROS<string?> for StringValues #101457
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -85,6 +85,26 @@ public static implicit operator StringValues(string?[]? values) | |
return value.GetArrayValue(); | ||
} | ||
|
||
#if NET9_0_OR_GREATER | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dotnet/area-extensions-primitives please advice if you want to expose this to ns2.0 too, it can't be allocation-free there. |
||
/// <summary> | ||
/// Defines an implicit conversion of a given <see cref="StringValues"/> to a string span. | ||
/// </summary> | ||
/// <param name="value">A <see cref="StringValues"/> to implicitly convert.</param> | ||
#pragma warning disable CS3006 // Overloaded method 'StringValues.implicit operator ReadOnlySpan<string?>(in StringValues)' differing only in ref or out, or in array rank, is not CLS-compliant. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks like an analyzer bug, see this sharplab sample too. |
||
public static implicit operator ReadOnlySpan<string?>(in StringValues value) | ||
#pragma warning restore CS3006 | ||
{ | ||
if (value._values is string) | ||
{ | ||
return new ReadOnlySpan<string?>(in Unsafe.As<object, string?>(ref Unsafe.AsRef(in value._values))); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this extremely unsafe? Other threads (or even the same thread) could overwrite the reference. _field = new("foo");
ReadOnlySpan<string> span = _field;
_field = new(["bar"]);
if (span[0].GetType() != typeof(string))
{
Console.WriteLine("Oh no");
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a very good catch. And I don't see a good way to achieve what the method needs to achieve and still be able to make it safe. I think that means we need to scrap this API. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
@stephentoub don't we want change to the allocating form? if (value._values is string s)
{
return new ReadOnlySpan<string?>([s]);
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'd be ok with that in this case, but there were several folks who voiced opposition to having a span-returning API like this that allocated. |
||
} | ||
else | ||
{ | ||
return new ReadOnlySpan<string?>((string?[]?)value._values); | ||
} | ||
} | ||
#endif | ||
|
||
/// <summary> | ||
/// Gets the number of <see cref="string"/> elements contained in this <see cref="StringValues" />. | ||
/// </summary> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We generally don't use ifdefs in ref files. You'll want to create a separate Microsoft.Extensions.Primitives.netcoreapp.cs next to this one with just the new API, e.g. https://github.com/dotnet/runtime/blob/main/src/libraries/System.IO.Hashing/ref/System.IO.Hashing.netcoreapp.cs