如何检测全球化不变模式

Kla*_*ter 5 c# globalization .net-6.0 .net-7.0

.NET Core/6/7 支持全球化不变模式,该模式以多种方式改变有关全球化的行为。

库如何检测它是否在此模式下运行并相应地调整其行为?

到目前为止,我提出的唯一解决方案是利用这样一个事实:由于 .NET 6 创建的文化不是此模式下的不变文化,因此(根据本文档)会抛出CultureNotFoundException.

bool IsGlobalizationInvariantModeEnabled()
{
  try
  {
    _ = new CultureInfo("en-US");
    return false;
  }
  catch (CultureNotFoundException)
  {
    return true;
  }
}
Run Code Online (Sandbox Code Playgroud)

我不喜欢这个解决方案,因为它滥用了例外,并且还假设如果未激活全球化不变模式,“en-US”文化始终可用。

有没有更好的办法?

Gur*_*ron 5

似乎没有公共 API 可以实现这一点。您可以尝试分析相应的AppContext开关和环境变量:

\n
var isInvariantGLob = GetBooleanConfig("System.Globalization.Invariant", "DOTNET_SYSTEM_GLOBALIZATION_INVARIANT");\n\nstatic bool GetBooleanConfig(string switchName, string envVariable, bool defaultValue = false)\n{\n    if (!AppContext.TryGetSwitch(switchName, out bool ret))\n    {\n        string? switchValue = Environment.GetEnvironmentVariable(envVariable);\n        ret = switchValue != null \n            ? (switchValue.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase) || switchValue.Equals("1")) \n            : defaultValue;\n    }\n \n    return ret;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

基本上,内部完成相同的操作 - 在GlobalizationMode.

\n

UPD

\n

创建了公开公开的API 提案GlobalizationMode

\n

UPD2

\n

正如 API 提案讨论中所解释的,此方法对于 AOT/修剪场景实际上并不可靠:

\n
\n

在存在修整的情况下,开关并不是检测不变模式的可靠方法。修剪可以将应用程序硬编码为“始终不变模式”或“从不不变模式”。在这种情况下,该开关将被忽略。

\n
\n

因此,建议采用与您类似的异常方法(尽管根据讨论它有自己的边缘情况):

\n
private static bool IsGlobalizationInvariantModeEnabled()\n{\n    try\n    {\n        return CultureInfo.GetCultureInfo("en-US").NumberFormat.CurrencySymbol == "\xc2\xa4";\n    }\n    catch (CultureNotFoundException)\n    {\n        return true;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n