Runtime: API proposal: Extend CultureInfo.GetCultureInfo and new CultureInfo to optionally accept predefined cultures only

Created on 10 Sep 2018  路  12Comments  路  Source: dotnet/runtime

Follow-up from dotnet/runtime#16457

Rationale and Use Cases

Surprisingly, since Windows _10_ and on Unix-like platforms, CultureInfo.GetCultureInfo(<name>) and also new CultureInfo(<name>) implicitly _create_ (custom) cultures, if <name> does not refer to any of the cultures reported by CultureInfo.GetCultures(CultureTypes.AllCultures) - as long as <name> is _formally_ a valid culture name (which varies by platform).

This makes it cumbersome to ensure that a given culture name refers to a _predefined_ culture - manual validation of the name of the CultureInfo instance returned against the list of predefined cultures reported by CultureInfo.GetCultures(CultureTypes.AllCultures) is necessary.

Arguably, throwing an exception if a non-predefined culture name is used should be the _default_ (whereas _creation_ of a custom culture should be a deliberate act), but changing this is no longer an option.

An example use case is a helper function in PowerShell for convenient testing of culture-sensitive functionality, Use-Culture, to which you pass the name of a predefined culture; e.g., Use-Culture de-DE { 1.2 } outputs 1,2, reflecting the culture-specific decimal mark, ,. The intent is to test with _predefined_ cultures, so a _typo_ such as Use-Culture de_DE { 1.2 } should result in an _error_, as opposed to - unintended - ad-hoc creation of a culture.
The proposed API extension would would allow the function to test the validity of a given culture name directly, without having to search through the array of predefined cultures returned by CultureInfo.GetCultures(CultureTypes.AllCultures).

A pending enhancement to the Get-Culture cmdlet would benefit similarly.

Proposed API

Introduce a Boolean predefinedOnly parameter which ensures that only the names of predefined cultures are accepted and throws a System.Globalization.CultureNotFoundException exception otherwise:

public static System.Globalization.CultureInfo GetCultureInfo (string name, bool predefinedOnly);

// Note: Since a CultureInfo (string, bool) constructor already exists, the parameter can only
//           be *added* to it.
public CultureInfo (string name, bool useUserOverride, bool predefinedOnly);

Note that both signatures are needed, because only the constructor form enables retrieval of culture information that reflects user overrides (user-specific tweaks to a predefined culture via Control Panel).

@tarekgh suggests holding off on implementing the following signature until the need arises, if ever:

public static System.Globalization.CultureInfo GetCultureInfo (string name, string altName, bool predefinedOnly);
api-approved area-System.Globalization

All 12 comments

Thanks, @mklement0

Do we really need
```C#
public static System.Globalization.CultureInfo GetCultureInfo (string name, string altName, bool predefinedOnly);

Also, I don't think we can have 
```C#
public CultureInfo (string name, bool predefinedOnly);

because we already have the constructor that takes a string and boolean parameters. this need to change.

Would it be better to have TryGetCultureInfo family which can return bool and not throwing?

```C#

static bool TryeGetCultureInfo(string name, out CultureInfo culture);
static bool TryeGetCultureInfo(string name, bool userOverride, out CultureInfo culture);
static bool TryeGetCultureInfo(string name, bool userOverride, bool predefinedOnly, out CultureInfo culture);

```

Good point re public CultureInfo (string name, bool predefinedOnly), thanks - I've removed it from the OP.


Re whether we need GetCultureInfo (string name, string altName, bool predefinedOnly):

I think so, yes, because it's likely that you want to ensure that altName too refers to an _existing_ culture.


While _also_ having TryGetCultureInfo methods wouldn't hurt, I wouldn't _only_ provide that, because if the user's intent to is _retrieve a preexisting culture that they assume indeed exists_, it is awkward to frame that in terms of a _try_ - Try*() methods are for situations where you _anticipate_ failure, which is not the case here.

I think so, yes, because it's likely that you want to ensure that altName too refers to an existing culture.

I am asking if you are going to use it? we can expose this later as needed. I want to ensure we expose only what is needed in your scenario.

For TryGetCultureInfo, I'll not add here for now if we are going to expose a new constructors or GetCultureInfo override

I am asking if you are going to use it?

No, in the context of PowerShell I'm not aware of a need for a GetCultureInfo (string name, string altName) overload that enforces use of preexisting culture names only.

Out of curiosity, however: why not make that change too, for consistency? Almost seems easier than leaving users to wonder about this omission.

Out of curiosity, however: why not make that change too, for consistency? Almost seems easier than leaving users to wonder about this omission.

Your scenario is really not the main scenario. I am not expecting many others will use this. this is why I don't want to expose something nobody else will use it. if we get a request later to have it, we can add it at any time.

@mklement0 could you please update the top description with the final proposal as we discussed it here? please follow the proposal format (look at the issue as an example https://github.com/dotnet/corefx/issues/28944). thanks.

@tarekgh, please see if my update to the OP is what you had in mind.

please see if my update to the OP is what you had in mind.

LGTM. thanks.

cc @krwq

Video

After some debate we settled on this:

C# namespace System.Globalization { public partial class CultureInfo { public static CultureInfo GetCultureInfo(string name, bool prefinedOnly); } }

This API would throw for invalid names as well as names that weren't system provided when predefinedOnly is true.

Correct. I've fixed the comment.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

EgorBo picture EgorBo  路  3Comments

GitAntoinee picture GitAntoinee  路  3Comments

jkotas picture jkotas  路  3Comments

matty-hall picture matty-hall  路  3Comments

bencz picture bencz  路  3Comments