【问题标题】:OrderBy does not work on my computer onlyOrderBy 仅在我的计算机上不起作用
【发布时间】:2020-11-09 14:04:21
【问题描述】:

我们首先有一个用于数据库的旧式 db gen 工具。我在没有实际更改的情况下对内容进行更改。我把它归结为列的排序。

Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("sv-SE");
var sortThis = new[] { "VatNumber", "VisiAvtalsnummerCompanies", "WinZipPassword" }
    .OrderBy(s => s, StringComparer.CurrentCultureIgnoreCase)
    .ToList();

输出应该是“VatNumber”、“VisiAvtalsnummerCompanies”、“WinZipPassword”,在瑞典文化中 V 在字母表中排在 W 之前。

但在我的电脑上输出的是“VatNumber”、“WinZipPassword”、“VisiAvtalsnummerCompanies”

C# fiddle 上的服务器输出正确

https://dotnetfiddle.net/sXJjD6

编辑:

StringComparer.Create(new CultureInfo("sv-SE"), true)
                .Compare("V", "W"); // -1  correct

StringComparer.Create(new CultureInfo("sv-SE"), true)
                .Compare("VB", "WA"); // 1  incorrect

【问题讨论】:

  • 如果将StringComparer.CurrentCultureIgnoreCase 替换为StringComparer.Create(new CultureInfo("sv-SE"), true) 会发生什么?
  • 如果它正在排序 V - W - V 那么它不是排序。这似乎不太可能,但是当似乎发生了不可能的事情时,总是有一个不正确的假设。我最好的猜测是它是按字符串长度排序的。这意味着本地执行的代码可能不是你想象的那样。
  • 只是一个想法。在大多数情况下,使用的区域性设置是从您机器的区域设置中检索的。因此,如果您已指定您的机器区域为sv-SE,但您已经否决了这些设置,那么您的区别就在于此。你有没有和别人的机器比较过?
  • 有时在您的源代码中存在隐藏的不可打印字符——尤其是当这些字符通过复制粘贴来自网页时。您能否仔细检查字符串是否正确编码且没有隐藏字符? (我问这个是因为小提琴与这篇文章中的代码并不是逐个字符相同的——添加了 cmets,所以它们表面上并不相同。)
  • 这可能是相关的吗? Culture sv-SE sort order for strings does not handle the order of v and w correctly?它只是强化了罪魁祸首可能与操作系统有关。

标签: c# sorting globalization


【解决方案1】:

在 2006 年之前,似乎 V 和 W 在瑞典语中的排序相同:似乎瑞典语并没有真正使用 W(除了在名称和导入词中),而且 V 和 W 有时可以互换使用,所以这个排序顺序选择是为了减少混淆 [1]。

早在 2006 年,第 13 版 SAOL(Svenska Akademiens OrdLista;瑞典语的参考词典)宣布 W 本身就是一个字母,并开始将它作为 V 的一个单独字母进行分类。

定义此类内容的 Unicode 通用语言环境数据存储库 CLDR 为瑞典语引入了两种排序规则:“标准”和“改革”。他们在 2007 年 [2] 将默认排序规则更改为“reformed”,这会影响使用 CLDR 作为参考的任何内容。

Windows 在 1903 更新中集成了使用 CLDR 数据的国际 Unicode 组件 (ICU)。但是,这只会影响 .NET 5:较早的 .NET 版本仍应使用国家语言支持 (NLS) 库 [3]。

我无法找到任何有关 NLS 版本 1909 和 2004 之间更改的数据。我不知道他们最终可能赶上了 CLDR。在 Windows 7 中对排序进行了一些重大更改,但自 [4] 以来我找不到任何东西。如果您的目标是 .NET 5,并从 1903 升级,那么我可以解释一下。

如果您的目标是 .NET 5+,或者在 Linux 上运行,您应该一直使用 CLDR 数据。

[1]:https://en.wikipedia.org/wiki/Swedish_alphabet#Uncommon_letters
[2]:https://github.com/unicode-org/cldr/commit/aaa134f4f74db91b781be1c8b9d9e9f1fd123c0e
[3]:https://docs.microsoft.com/en-us/dotnet/standard/globalization-localization/globalization-icu
[4]:https://docs.microsoft.com/en-us/windows/win32/win7appqual/nls-sorting-changes

我遇到的其他随机链接,但未构成我的答案的一部分:

  1. https://unicode-org.atlassian.net/browse/CLDR-1035#icft=CLDR-1035
  2. https://unicode-org.atlassian.net/browse/CLDR-2143?jql=text%20~%20%22swedish%20collation%22
  3. https://sourceware.org/bugzilla/show_bug.cgi?id=9724
  4. https://bugzilla.redhat.com/show_bug.cgi?id=17005
  5. Sort list of tuples considering locale (swedish ordering)
  6. http://www.softwolves.pp.se/misc/arkiv/sv/18/9009.html
  7. How to get Swedish sort order for strings
  8. https://github.com/dotnet/runtime/issues/29592

【讨论】:

  • 在 1909 年,我在完整框架 4.8 和 .NET Core 3.1 上都遇到了问题。 2004 年更新修复了这两个问题。
  • 当时 NLS 一定是在 2004 年终于更新到了改革后的排序规则,但我找不到任何真正说明这一点的变更说明。
猜你喜欢
  • 2016-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-02
  • 2011-12-22
  • 1970-01-01
  • 2011-03-30
  • 1970-01-01
相关资源
最近更新 更多