使用 .NET 4.8 / 全球化的 C# 11 中的 SortedDictionary 存在问题

问题描述 投票:0回答:1

网站使用用户当前的文化来显示数据。来自越南的用户访问数据时出现问题。有人可以解释为什么会出现这个问题吗? 重现错误的代码:

static void SortedDicProblem(Action<string> Write)
{
    Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

    const string key = "KH";

    SortedDictionary<string, string> laCountries = new()
    {
        { key, "Kambodscha " },
        { "KI", "Kiribati " },
        { "KM", "Komoren " },
    };

    foreach (CultureInfo loCult in System.Globalization.CultureInfo.GetCultures(CultureTypes.InstalledWin32Cultures))
    {
        Test(loCult.Name);
    }

    void Test(string vsCulture)
    {
        Thread.CurrentThread.CurrentCulture = new CultureInfo(vsCulture);

        if (laCountries.TryGetValue(key, out string lsName))
        {
            Write($"{vsCulture}");
        }
        else
        {
            Write($"<span class='error'>{vsCulture}, Key not found: {key}, {Thread.CurrentThread.CurrentCulture.EnglishName}</span>");
        }
    }
}

我们会知道如何解决这个问题,但是这个错误的原因是什么? 避免该问题的解决方案:使用 StringComparer 实例化 SortedDictionary,例如:

new SortedDictionary<string,string>(StringComparer.Ordinal)
c# internationalization cultureinfo sorteddictionary
1个回答
0
投票

这是问题(出现在 .NET 4.8 上,出现在 .NET 5+ 上):

public static void Main()
{
    var usComparer = StringComparer.Create(new CultureInfo("en-US"), ignoreCase: false);
    var veComparer = StringComparer.Create(new CultureInfo("vi-VN"), ignoreCase: false);

    Console.WriteLine(usComparer.Compare("KH", "KM")); // Prints -1
    Console.WriteLine(veComparer.Compare("KH", "KM")); // Prints  1
}

在美国英语中,“KH”被认为是“KM”之前。 在越南语中,“KH”被认为是“KM”之后

因为您已使用一个比较器将项目插入到字典中,然后尝试使用不同的比较器检索它们,这给出了不同的排序顺序,所以一切都崩溃了。

至于为什么它在 .NET 5+ 上有所不同——那是另一个问题了。我想这与以下事实有关:

.NET core 使用 ICU 进行字符串比较,而 .NET 4.8 不使用 ICU。

© www.soinside.com 2019 - 2024. All rights reserved.