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

[API Proposal]: string.ToTitleCase() extension method(s) #72269

Closed
SteveDesmond-ca opened this issue Jul 15, 2022 · 10 comments
Closed

[API Proposal]: string.ToTitleCase() extension method(s) #72269

SteveDesmond-ca opened this issue Jul 15, 2022 · 10 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Globalization needs-author-action An issue or pull request that requires more info or actions from the author.
Milestone

Comments

@SteveDesmond-ca
Copy link
Contributor

SteveDesmond-ca commented Jul 15, 2022

Background and motivation

I often find myself needing to title case strings, and the current API for doing so isn't so intuitive. As the action is being performed on the string, it seems more idiomatic for a .ToTitleCase() method to happen on the string itself.

API Proposal

public static class StringExtensions
{
    public static string ToTitleCase(this string str) => CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str);
    public static string ToTitleCase(this string str, CultureInfo culture) => culture.TextInfo.ToTitleCase(str);
}

API Usage

var bookName = "a tale of two cities";
var title = bookName.ToTitleCase();

var eh = new CultureInfo("en-CA");
var songName = "my favourite chords";
var title = songName.ToTitleCase(eh);

Alternative Designs

This could also be done as a single method with an optional culture parameter:

public static string ToTitleCase(this string str, CultureInfo? culture = null)
    => (culture ?? CultureInfo.CurrentCulture).TextInfo.ToTitleCase(str);

but I think the overload is probably a better choice, and aligns more with existing .NET API designs.

The method could also be called .ToTitle() to better align with .ToUpper() and ToLower(). This may also involve adding a .ToTitleInvariant() variant for consistency.

Risks

There's a chance that using the current culture as the default leads to undesired results based on incorrect developer assumptions, which may not be present when explicitly choosing a CultureInfo/TextInfo. I think this is a similar risk to how time zones are dealt with: certain actions use the host's current time zone by default.

@SteveDesmond-ca SteveDesmond-ca added the api-suggestion Early API idea and discussion, it is NOT ready for implementation label Jul 15, 2022
@ghost ghost added the untriaged New issue has not been triaged by the area owner label Jul 15, 2022
@ghost
Copy link

ghost commented Jul 15, 2022

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

Issue Details

Background and motivation

I often find myself needing to title case strings, and the current API for doing so isn't so intuitive. As the action is being performed on the string, it seems more idiomatic for a .ToTitleCase() method to happen on the string itself.

API Proposal

public static class StringExtensions
{
    public static string ToTitleCase(this string str) => CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str);
    public static string ToTitleCase(this string str, CultureInfo culture) => culture.TextInfo.ToTitleCase(str);
}

API Usage

var bookName = "a tale of two cities";
var title = bookName.ToTitleCase();

var eh = new CultureInfo("en-CA");
var songName = "my favourite chords";
var title = songName.ToTitleCase(eh);

Alternative Designs

This could also be done as a single method with an optional culture parameter:

public static string ToTitleCase(this string str, CultureInfo? culture = null)
    => (culture ?? CultureInfo.CurrentCulture).TextInfo.ToTitleCase(str);

but I think the overload is probably a better choice, and aligns more with existing .NET API designs.

The method could also be called .ToTitle() to better align with .ToUpper() and ToLower(). This may also involve adding .ToTitleInvariant() variants.

Risks

There's a chance that using the current culture as the default leads to undesired results based on incorrect developer assumptions, which may not be present when explicitly choosing a CultureInfo/TextInfo. I think this is a similar risk to how time zones are dealt with: certain actions use the host's current time zone by default.

Author: SteveDesmond-ca
Assignees: -
Labels:

api-suggestion, area-System.Globalization, untriaged

Milestone: -

@filipnavara
Copy link
Member

filipnavara commented Jul 15, 2022

. NET relies on ICU to do the case conversions. There is an API to title case a string but you would likely be disappointed with the result if default options are used. Neither the Unicode standard nor the CLDR have data for the stop words, so for lord of the flies you would get Lord Of The Flies instead of Lord of the Flies.

Since there are no standard data with the stop words you would likely need to expose a more advanced API where the user can supply a list.

@SteveDesmond-ca
Copy link
Contributor Author

How does the current TextInfo.ToTitleCase() handle it? This is really just syntactic sugar on top of that. Or are you saying (similar to the "Risks" section above) that there are different implications/assumptions if ToTitleCase() is called on a string?

@filipnavara
Copy link
Member

filipnavara commented Jul 15, 2022

How does the current TextInfo.ToTitleCase() handle it? This is really just syntactic sugar on top of that.

My bad, I didn't see that on mobile (the right part of the code block was a hidden). It doesn't handle stop words, you get "Lord Of The Flies". So if the ask is just syntactic sugar for that I guess it's fine (although it may run against the goals in dotnet/designs#207).

@SteveDesmond-ca
Copy link
Contributor Author

Yeah, we can tweak this so it better aligns with dotnet/designs#207 as well

@tarekgh
Copy link
Member

tarekgh commented Jul 15, 2022

@SteveDesmond-ca this kind nice to have a feature but nobody requested that for long time which can tell there is not much demand for it. Also, as @filipnavara, we are trying to not expose more things inside string class that can have implicit linguistic behavior. It is proven this causes a lot of pain and we are already in the process of working to enhance this experience. I suggest closing this issue as the workaround is easy and the proposal does not match the direction we want to go with.

I suggest closing this issue if that makes sense to you. Thanks for your report.

CC @GrabYourPitchforks

@tarekgh tarekgh removed the untriaged New issue has not been triaged by the area owner label Jul 15, 2022
@tarekgh tarekgh added this to the Future milestone Jul 15, 2022
@tarekgh tarekgh added the needs-author-action An issue or pull request that requires more info or actions from the author. label Jul 15, 2022
@ghost
Copy link

ghost commented Jul 15, 2022

This issue has been marked needs-author-action and may be missing some important information.

@SteveDesmond-ca
Copy link
Contributor Author

OK, I'll reconsider once dotnet/designs#207 has been implemented. At the very least, now there's an official record that this functionality is desired in some capacity!

@mscottford
Copy link

I realize this is closed, and a resolution has already been reached, but I’d still like to make a comment about the assertion that demand for this behavior is low.

Had I only worked in the .NET ecosystem, I might never have thought a ToTitleCase method was needed. Instead I would have just done a StackOverflow search, copied/pasted, and moved on. However, I’ve come to enjoy the rich set of methods that are available on Ruby’s String class. It’s when I come back to the .NET ecosystem that I wish I had the same wealth of methods defined on string. That said, my desire for a ToTitleCase method has never pushed me to create an issue like @SteveDesmond-ca did.

My point is that not all who are frustrated take the time to share their frustration, most just deal with it. If demand is only based on request count, then it is not going to generate an accurate picture.

It might be possible to determine demand by taking an inventory of packages that provide string extensions that implement the ToTitleCase behavior. The number of downloads on those packages might work as a stand in for demand.

@tarekgh
Copy link
Member

tarekgh commented Jul 20, 2022

It might be possible to determine demand by taking an inventory of packages that provide string extensions that implement the ToTitleCase behavior. The number of downloads on those packages might work as a stand in for demand.

Thanks @mscottford for your thoughts.

Looking at such an inventory will not tell if the demand on this specific API or something else. You can have an extension library that has tons of APIs and is used only for a few of them. We are not trying to shut down any idea or request here. Think about if we add most of the requested features to the framework while few users need these features.
It is ok to have such requested extension method written in the apps/libraries as it is simple enough. If you have more data we can consider, please let us know and we'll be happy to look at it.

@ghost ghost locked as resolved and limited conversation to collaborators Aug 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Globalization needs-author-action An issue or pull request that requires more info or actions from the author.
Projects
None yet
Development

No branches or pull requests

4 participants