【问题标题】:SortedDictionary ArgumentException: "Æ" and "AE" considered the same keysSortedDictionary ArgumentException:“Æ”和“AE”被认为是相同的键
【发布时间】:2015-05-27 08:41:13
【问题描述】:

我试图使用 SortedDictionary 从文件中存储我的一些数据,但得到了非常奇怪的一堆关键重复异常。我想出了下一个重现我的问题的代码示例:

var dict = new SortedDictionary<string, string>();
dict.Add("Æ", "qwerty"); // "aesc" (aka "ash"), single symbol
Console.WriteLine(dict["AE"]); // outputs "qwerty" for two-symbol string "AE"
dict.Add("AE", ""); // ArgumentException: An entry with the same key already exists.

This code on .NET Fiddle

不过,通常的 Dictionary 并没有发生这种情况,我最终决定改用它。但我仍然想知道为什么排序的问题是个问题?不幸的是,尽管 MS 最近开放了一些 .NET 源代码,但我自己无法通过谷歌搜索答案(有很多与 AES 相关的噪音)并且无法调试到 SortedDictionary 的代码。

这个类似乎隐式运行了一些字符串预处理/规范化函数,但我不敢相信这是一个实际原因。

任何想法为什么会发生?提前致谢!

【问题讨论】:

  • 因为string.Compare("Æ", "AE") == 0。查看备注here

标签: c# .net dictionary unique sorteddictionary


【解决方案1】:

这是因为文化。例如,试试new SortedDictionary(StringComparer.Ordinal)

Dictionary 行为不同的原因是它使用 EqualityComparer&lt;TKey&gt;.Default 而 SortedDictionary 使用 Comparer&lt;TKey&gt;.Default

【讨论】:

  • Comparer&lt;string&gt;.Default 最终使用String.Compare()
  • @MatthewWatson 实际上它使用IComparable&lt;string&gt; 实现,它调用CultureInfo.CurrentCulture.CompareInfo.Compare(string, string, CompareOptions),为选项传递零。见referencesource.microsoft.com/#mscorlib/system/string.cs,2114。此外,默认的相等比较器使用IEquatable&lt;string&gt; 实现,它进行序数比较。
  • @MatthewWatson 当然,String.Compare(string, string) 调用CultureInfo.CurrentCulture.CompareInfo.Compare(string, string, CompareOptions),所以就好像你说的是真的一样。见referencesource.microsoft.com/#mscorlib/system/string.cs,1756
  • 这正是我想要表达的:它最终的表现与string.Compare() 所做的完全一样。
  • @SimpleV 大概是因为大多数用户希望在默认情况下进行适合语言的排序。例如,“apple”应该放在“Berries”之前,但序数比较会将“Berries”放在“apple”之前。
猜你喜欢
  • 1970-01-01
  • 2010-10-02
  • 2013-09-04
  • 1970-01-01
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-05
相关资源
最近更新 更多