-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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]: Expose GlobalizationMode.Invariant
(and potentially others) publicly
#81429
Comments
Tagging subscribers to this area: @dotnet/area-system-globalization Issue DetailsBackground and motivationExpose members of API Proposalnamespace System.Globalization
{
public static partial class GlobalizationMode
{
public static bool IsInvariant => ...;
}
} API Usagevar isGlobalizationInvarinat = GlobalizationMode.IsInvariant; Alternative DesignsNo response RisksNo response
|
GlobalizationMode.Invariant
(and potentially) publiclyGlobalizationMode.Invariant
(and potentially others) publicly
Why is reading the settings not good enough for that? I don't think this is going to change at all in the future. // https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/Globalization/GlobalizationMode.cs,15
// https://source.dot.net/#System.Private.CoreLib/src/libraries/System.Private.CoreLib/src/System/AppContextConfigHelper.cs,13
public static bool IsInvariantMode()
{
if (!AppContext.TryGetSwitch("System.Globalization.Invariant", out bool ret))
{
string? switchValue = Environment.GetEnvironmentVariable("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT");
ret = switchValue != null ? switchValue.Equals("True", StringComparison.OrdinalIgnoreCase) || switchValue.Equals("1")) : false;
}
return ret;
} |
This issue has been marked |
@tarekgh because it requires some understanding of internal workings of the feature and leads to some inventive code even in Microsoft products as you see in the linked |
One problem is that even if this property was added today, existing libraries like By the time libraries would be free to only use this property, secure that it's part of the core runtime, we're several years down the road, limiting its usefulness. That's not to say it's an absolute argument against, of course. |
don't take this as push back on the proposal idea.
The switches are public and documented so it is not internal. But I got a related point which makes reading the config switches are not reliable enough. I'll mention that later in this reply.
I do not see this compelling argument to expose API for especially the workaround is not big. Here are some thoughts:
If need to have temporary workaround for now, I suggest you do something like the following: public enum InvariantMode
{
None,
PredefinedCultureOnly,
AllCultures
}
public static InvariantMode Invariant { get; } = GetInvariantMode();
private static InvariantMode GetInvariantMode()
{
try
{
return CultureInfo.GetCultureInfo("en-US").NumberFormat.CurrencySymbol == "¤" ? InvariantMode.AllCultures : InvariantMode.None;
}
catch (CultureNotFoundException)
{
return InvariantMode.PredefinedCultureOnly;
}
} If you care only if Invariant mode is on or off, you may simplify that as public static bool Invariant { get; } = GetInvariantMode();
private static bool GetInvariantMode()
{
try { return CultureInfo.GetCultureInfo("en-US").NumberFormat.CurrencySymbol == "¤" ; }
catch (CultureNotFoundException) { return true;}
} |
The switch is not reliable way to detect invariant mode in the presence of trimming. Trimming can hardcode the app to "always invariant mode" or "never invariant mode". The switch is ignored in that case. |
This code may throw an exception when nothing's wrong, just to detect behavior. Such exceptions cause noise and slowdowns when debugging (even if it happens just once at startup, since it still requires developer attention every time). This is not a dealbreaker, but still annoying. Worse, like the code applied in |
Using |
That is what I was trying to say in the second bullet in my reply. |
Shouldn't this be |
You are right. I fixed it in the code. |
Is there any possibility that the |
Currently |
Is that valid statement even for configurations with custom ICU builds? IIRC, custom ICU builds can be trimmed down in number of ways. |
Are you referring to the buildings for WASM and mobile apps? CC @akoeplinger @ilonatommy if they add more details as needed. |
@tarekgh Here is another example were this API can be useful - Humanizr/Humanizer#1213 instead of unnecessary exception management. |
@gurustron I am not pushing back having API for that :-) what I have provided before just a workaround to use till we have the API. That is why I am keeping the issue open for tracking. |
@tarekgh great, thank you! |
That is true but actually we are thinking also about introducing a "real" custom ICU option for WASM where loading ICU bundles that contain a custom set of locales for specific app (nothing prevents from creating such ICU without en-US) will be possible. It is motivated by the fact that some customers require locales that are not present in the default ICU for WASM and we don't want to increase the size of the default ICU bundle. |
I guess it ultimately comes down to why a library is trying to detect GIM and what happens if it doesn't. For example, for something like For a library like Humanizer, the problem specifically only occurred because it used
Bottom line is that detecting GIM as a flag should be unusual because what clients ought to be doing is checking for support for the cultures they need -- but they currently can't do this without handling exceptions or by inefficiently enumerating |
In my opinion given all the edge cases that were already listed pushing the checking code onto the end user doesn't seem viable to me. I like the |
In our case it is that we want to skip a rather expensive process (involving loading translations) that is definetely not useful with GIM. |
@KGuetter: but which translations? If the user has enabled a customized set of locales, would it be beneficial to only load those? In other words, might you be better off by checking what's in |
@jeroen-mostert What you suggest might indeed also be a workaround: Check if |
For the scenario where you may proficiently use the cultures for limiting translations anyway, yes. Not necessarily universally, because I imagine getting all the cultures (even if just to check there's only one) might have considerable overhead in other scenarios (I haven't actually benchmarked it). It'll almost certainly be slower than just checking if there's no |
If you are going to support that, you need to think about the resource fallback handling. Currently all .NET libraries have
This comes everywhile and I agree it is worth considering this API too.
I fully agree with that, that is what I tried to point at in the third bullet of my reply #81429 (comment).
Enumeration is not enough here either because there are aliased cultures which are not returned by the enumeration but still valid. But, in general I agree checking for GIM should be unusual and needed only in specific situations. In general, I can see some libraries will not work properly (or will not work at all) in GIM, but this is part of the GIM contract that apps who enable GIM understand they will get some restrictions. |
The problem there is twofold:
For the scenarios that this proposal was inspired by, it's not a simple case of "well you asked for it, you got it, what did you expect?" |
Thinking a little more, I think the best solution here is like what @jeroen-mostert mentioned before with a little modification. We can expose Doing that will give full flexibility to the libraries and not need to check any culture property like currency symbol. Also, this API can be super useful even for non-GIM. |
Background and motivation
Expose members of
GlobalizationMode
publicly. There is request for that:API Proposal
API Usage
Alternative Designs
No response
Risks
No response
The text was updated successfully, but these errors were encountered: