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

String.TrimStart trims unexpected characters in dotnet 9 #103892

Closed
Zeegaan opened this issue Jun 24, 2024 · 8 comments
Closed

String.TrimStart trims unexpected characters in dotnet 9 #103892

Zeegaan opened this issue Jun 24, 2024 · 8 comments

Comments

@Zeegaan
Copy link

Zeegaan commented Jun 24, 2024

Description

In dotnet 9, the behavior of String.TrimStart is very different to 8
If you have a string like "Hello this is my string", and you do .TrimStart on it with "Hello this".
The result is "my string".
Also TrimStart is now Case sensitive, which it wasn't before, so maybe TrimStart should be able to pass a StringComparison parameter.

Reproduction Steps

Console app

You can do this quickly in a console app like this:

string start = "Hello this is my string";

string trimmed = start.TrimStart("Hello this");

Console.WriteLine(trimmed);
  • note that trimmed will be "my string", and not "is my string" as expected.

Unit tests

Setup a unit test like so:

[TestCase("Hello this is my string", "hello", " this is my string")]
[TestCase("Hello this is my string", "Hello this", " is my string")]
[TestCase("Hello this is my string", "Hello this is my ", "string")]
public void TrimStart(string input, string forTrimming, string shouldBe)
{
    var trimmed = input.TrimStart(forTrimming);
    Assert.AreEqual(shouldBe, trimmed);
    StringComparison.OrdinalIgnoreCase
}
  • Run unit tests
  • These should all pass according to dotnet 8 behavior

Expected behavior

Expected behavior should be the "shouldBe" strings

Actual behavior

TrimStart trims more words than it should, and is now case sensitive.

Regression?

Guess this could be new behavior in dotnet 9, but still strange that it trims more words than it should

Known Workarounds

No response

Configuration

This is running on dotnet 9.0.100-preview.5
Windows x64

Other information

No response

@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Jun 24, 2024
@dotnet-policy-service dotnet-policy-service bot added the untriaged New issue has not been triaged by the area owner label Jun 24, 2024
@Zeegaan Zeegaan changed the title String.TrimStart trims unexpected characters String.TrimStart trims unexpected characters in dotnet 9 Jun 24, 2024
@huoyaoyuan huoyaoyuan added area-System.Runtime and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Jun 24, 2024
@huoyaoyuan
Copy link
Member

There is no overload of TrimStart(string), but only TrimStart(ReadOnlySpan<char>). In this case, the forTrimming parameter is interpreted as a collection of characters, instead of a string. It's #102822 (comment) again.

In dotnet 9, the behavior of String.TrimStart is very different to 8

How can you do this in .NET 8? There wasn't a TrimStart(string) overload.

@huoyaoyuan
Copy link
Member

I think we should review the new API again before .NET 9 releases. It is already confusing people.

@Zeegaan
Copy link
Author

Zeegaan commented Jun 24, 2024

There is no overload of TrimStart(string), but only TrimStart(ReadOnlySpan<char>). In this case, the forTrimming parameter is interpreted as a collection of characters, instead of a string. It's #102822 (comment) again.

In dotnet 9, the behavior of String.TrimStart is very different to 8

How can you do this in .NET 8? There wasn't a TrimStart(string) overload.

We have been using TrimStart and passing in a string since 2013 it seems 😅
The unit tests I've provided are from there at least 🤣

@rhuijben
Copy link

I wouldn't be surprised if this is related to

https://stackoverflow.com/questions/4335878/c-sharp-trimstart-with-string-parameter

We have something similar in our codebase.

The pains of extension methods...

@huoyaoyuan
Copy link
Member

We have been using TrimStart and passing in a string since 2013 it seems 😅

It's probably some extension method implemented by yourself or some third-party package. You can navigate the code and confirm it.
Since the new TrimStart(ReadOnlySpan<char>) is an instance method, it wins over extension method even if the parameter type is less close.

@tannergooding
Copy link
Member

I think we should review the new API again before .NET 9 releases. It is already confusing people.

API review already extensively discussed this and had even more weigh in when the initial questions were raised. I don't expect we will change our stance that overloads need to have consistent behavior. At best I could see us not exposing the overload, but that hurts the overall ecosystem more as devs no longer have an allocation free way to achieve the trimming support.

New cases of potential breaks are of course interesting, but we've also historically never quantified us exposing new APIs on the core types, with regards to how they can cause a user-defined extension method to no longer be selected, as a blocking type of break,. This is because quantifying such changes as blocking would make it impossible for us to version our own types and expose new APIs.

CC. @bartonjs, @stephentoub

@Zeegaan
Copy link
Author

Zeegaan commented Jun 24, 2024

@huoyaoyuan You are right, it was an extension method 👍

@Zeegaan Zeegaan closed this as completed Jun 24, 2024
@dotnet-policy-service dotnet-policy-service bot removed the untriaged New issue has not been triaged by the area owner label Jun 24, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Jul 25, 2024
@AndyAyersMS
Copy link
Member

Also see ThreeMammals/Ocelot#2145

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants