Skip to content
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

Closed
wants to merge 1 commit into from

Conversation

jozkee
Copy link
Member

@jozkee jozkee commented Apr 23, 2024

Contributes to #101261.

Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-extensions-primitives
See info in area-owners.md if you want to be subscribed.

@@ -85,6 +85,26 @@ public StringValues(string?[]? values)
return value.GetArrayValue();
}

#if NET9_0_OR_GREATER
Copy link
Member Author

Choose a reason for hiding this comment

The 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.

/// 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.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like an analyzer bug, see this sharplab sample too.

#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.
public static implicit operator System.ReadOnlySpan<string?> (in Microsoft.Extensions.Primitives.StringValues value) { throw null; }
#pragma warning restore CS3006
#endif
Copy link
Member

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

{
if (value._values is string)
{
return new ReadOnlySpan<string?>(in Unsafe.As<object, string?>(ref Unsafe.AsRef(in value._values)));
Copy link
Member

Choose a reason for hiding this comment

The 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.
The rest of StringValues is careful to always do Unsafe only on locals that it already type checked.

_field = new("foo");
ReadOnlySpan<string> span = _field;
_field = new(["bar"]);

if (span[0].GetType() != typeof(string))
{
    Console.WriteLine("Oh no");
}

Copy link
Member

Choose a reason for hiding this comment

The 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.

Copy link
Member Author

@jozkee jozkee Apr 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to scrap this API.

@stephentoub don't we want change to the allocating form?

if (value._values is string s)
{
    return new ReadOnlySpan<string?>([s]); 
}

Copy link
Member

@stephentoub stephentoub Apr 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to scrap this API.

@stephentoub don't we want change to the allocation form?

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.

@stephentoub stephentoub added the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Apr 24, 2024
@jozkee jozkee closed this Apr 24, 2024
@jozkee jozkee deleted the stringvalues-op_implicit branch April 24, 2024 16:25
@github-actions github-actions bot locked and limited conversation to collaborators May 25, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-Extensions-Primitives NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants