Windows Universal 中的 CultureInfo 之间存在不一致

Inconsistencies between CultureInfo in Windows Universal

我需要从 UWP 应用程序生成一个 .CSV 文件,所以我正在使用 TextInfo.ListSeparator。

我发现系统设置与代码返回的值不一致。

使用区域设置:

使用 TextInfo Class:

TextInfo textInfo = System.Globalization.CultureInfo.CurrentCulture.TextInfo;
System.Diagnostics.Debug.WriteLine(textInfo.CultureName);
System.Diagnostics.Debug.WriteLine(textInfo.IsReadOnly);
System.Diagnostics.Debug.WriteLine(textInfo.ListSeparator);
System.Diagnostics.Debug.WriteLine(textInfo.IsRightToLeft);

我的系统配置:

已编辑 正如一些答案所建议的那样,我重新启动了我的电脑。然后编写了一个 UWP 和一个使用相同代码的 Windows Forms 应用程序。为了比较我 运行 一个 Windows PowerShell。值仍然不同,如下图所示。

PowerShell 和 Windows 表单返回了预期结果,但 UWP 失败。

这对我有效。

我认为是因为您更改设置后没有重新打开visual studio。

更改设置后,它不会通知并强制visual studio(或其他应用程序)已打开更改其环境值。您必须关闭并重新打开 visual studio 才能让 visual studio 以新设置开始。

[更新]

我成功了,因为我认为您只想更改 ListSeparator 设置,但没有更改区域格式。 @user5596450 方向正确。所以你的问题的答案是。您无法获取您在区域设置中指定的自定义区域格式。

实际上,自定义设置并非适用于所有设备系列。我相信目前的结果是有道理的。您所期望的应该由 UWP 的桌面扩展之类的东西提供,而不是 .net 核心 APIs。您可以随时向 wpdev.uservoice.com 提出请求,Microsoft 正在那里听取开发人员的反馈。

作为替代方案,.Net core API 将检查 UWP 应用程序的 PreferredLanguage 并为您获取相应的设置。例如,如果您在 UWP 应用程序中调用 Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = "pt-br";(通常在 App.xaml.cs 中的 OnLaunched 事件中),您将得到您期望的 但那不是来自 设置您在区域设置中自定义。这就是针对不同设备系列的通用应用程序的工作方式。请查看 ApplicationLanguages.PrimaryLanguageOverride MSDN 文档以了解其实际作用。

仅供参考,UWP 使用的 .net 核心 API 中的 CurrentCulture 可以在 github 上找到。这是它的实现方式:

public static CultureInfo CurrentCulture
{
    get
    {
        Contract.Ensures(Contract.Result<CultureInfo>() != null);

#if !FEATURE_CORECLR
        return Thread.CurrentThread.CurrentCulture;
#else
                // In the case of CoreCLR, Thread.m_CurrentCulture and
                // Thread.m_CurrentUICulture are thread static so as not to let
                // CultureInfo objects leak across AppDomain boundaries. The
                // fact that these fields are thread static introduces overhead
                // in accessing them (through Thread.CurrentCulture). There is
                // also overhead in accessing Thread.CurrentThread. In this
                // case, we can avoid the overhead of Thread.CurrentThread
                // because these fields are thread static, and so do not
                // require a Thread instance to be accessed.
#if FEATURE_APPX
                if(AppDomain.IsAppXModel()) {
                    CultureInfo culture = GetCultureInfoForUserPreferredLanguageInAppX();
                    if (culture != null)
                        return culture;
                }
#endif
                return Thread.m_CurrentCulture ??
                    s_DefaultThreadCurrentCulture ??
                    s_userDefaultCulture ??
                    UserDefaultCulture;
#endif
    }

    set
    {
#if FEATURE_APPX
                    if (value == null) {
                        throw new ArgumentNullException("value");
                    }                    

                    if (AppDomain.IsAppXModel()) {
                        if (SetCultureInfoForUserPreferredLanguageInAppX(value)) {
                            // successfully set the culture, otherwise fallback to legacy path
                            return; 
                        }
                    }
#endif
        Thread.CurrentThread.CurrentCulture = value;
    }
}

上面的答案可能是正确的。然而,更可能的原因是 Win32 或系统 API 使用基于特定区域格式设置(在本例中为 pt-BR)的区域设置数据,即“;”。 UWP 使用 WinRT API,它使用基于 Windows 显示语言(在本例中为 en-US)的区域设置数据,即“,”。