问题描述
这是任何工作的基本规律是运营商的。
在.NET,这不是为某些字符串真:
静态无效CompareBug()
{
字符串x =\\\-\\\ア; //或只是 - ア如果charset允许
字符串Y =\\\あ; //或只是あ如果charset允许
Console.WriteLine(则x.compareTo(Y)); //积极的
Console.WriteLine(y.CompareTo(X)); //积极的
Console.WriteLine(StringComparer.InvariantCulture.Compare(X,Y)); //积极的
Console.WriteLine(StringComparer.InvariantCulture.Compare(Y,X)); //积极的
变种JA = StringComparer.Create(新的CultureInfo(JA-JP,假),FALSE);
Console.WriteLine(ja.Compare(X,Y)); //积极的
Console.WriteLine(ja.Compare(Y,X)); //积极的
}
您看到 X
严格大于 y大
和是
严格大于 X更大。
由于则x.compareTo(X)
等都给予零( 0
),很显然,这不是一个数量级。毫不奇怪,我得到不可预知的结果,当我排序
数组或含有类似字符串列表X
和是
。虽然我没有测试过这一点,我相信 SortedDictionary<字符串,不管>
将保持自己在有序和/或定位,如果字符串的项目,如问题 X
和 Y / code>用于密钥。<
是?这个bug知名受到影响什么框架版本(我想这与.NET 4.0)
编辑:
在此处,符号为负任何一种方式的例子:
X =\\\一\\\゠; //当量:一゠
Y =\\\一\\\-\\\A; //当量:一-A
解决方案 我来了跨越这一SO后,当我试图找出为什么我有检索已插入到一个排序列表(字符串)键的问题后,我发现原因是净40及以上comparers(A1中的古怪行为; a2和A2&下; A3,但A1> A3)。
我的奋斗弄清楚发生了什么事情可以在这里找到:的
您可能想看看我的SO问题的更新3部分。看来,这个问题被报告给微软在2012年12月和2013年1月的末日,因为不会被固定的前关闭。此外,它列出了可以使用的解决方法。
我创造了这个建议的解决方法的实现,并验证它固定,我曾遇到的问题。我也只是验证了该解决您报告的问题。
公共静态无效SO_13254153_Question()
{
字符串x =\\\-\\\ア; //或只是 - ア如果charset允许
字符串Y =\\\あ; //或只是あ如果charset允许
变种invariantComparer =新WorkAroundStringComparer();
变种japaneseComparer =新WorkAroundStringComparer(新System.Globalization.CultureInfo(JA-JP,FALSE));
Console.WriteLine(则x.compareTo(Y)); //积极的
Console.WriteLine(y.CompareTo(X)); //积极的
Console.WriteLine(invariantComparer.Compare(X,Y)); //负一
Console.WriteLine(invariantComparer.Compare(Y,X)); //积极的
Console.WriteLine(japaneseComparer.Compare(X,Y)); //负一
Console.WriteLine(japaneseComparer.Compare(Y,X)); //积极的
}
剩下的问题是,这种变通办法这么慢呢是几乎没有实际用于处理字符串的大集合使用。所以,我希望微软将重新考虑关闭这个问题,或者一个更好的解决办法的有人知道。
It's a requirement for any comparison sort to work that the underlying order operator is transitive and antisymmetric.
In .NET, that's not true for some strings:
static void CompareBug()
{
string x = "\u002D\u30A2"; // or just "-ア" if charset allows
string y = "\u3042"; // or just "あ" if charset allows
Console.WriteLine(x.CompareTo(y)); // positive one
Console.WriteLine(y.CompareTo(x)); // positive one
Console.WriteLine(StringComparer.InvariantCulture.Compare(x, y)); // positive one
Console.WriteLine(StringComparer.InvariantCulture.Compare(y, x)); // positive one
var ja = StringComparer.Create(new CultureInfo("ja-JP", false), false);
Console.WriteLine(ja.Compare(x, y)); // positive one
Console.WriteLine(ja.Compare(y, x)); // positive one
}
You see that x
is strictly greater than y
, and y
is strictly greater than x
.
Because x.CompareTo(x)
and so on all give zero (0
), it is clear that this is not an order. Not surprisingly, I get unpredictable results when I Sort
arrays or lists containing strings like x
and y
. Though I haven't tested this, I'm sure SortedDictionary<string, WhatEver>
will have problems keeping itself in sorted order and/or locating items if strings like x
and y
are used for keys.
Is this bug well-known? What versions of the framework are affected (I'm trying this with .NET 4.0)?
EDIT:
Here's an example where the sign is negative either way:
x = "\u4E00\u30A0"; // equiv: "一゠"
y = "\u4E00\u002D\u0041"; // equiv: "一-A"
解决方案 I came across this SO post, while I was trying to figure out why I was having problems retrieving (string) keys that were inserted into a SortedList, after I discovered the cause was the odd behaviour of the .Net 40 and above comparers (a1 < a2 and a2 < a3, but a1 > a3).
My struggle to figure out what was going on can be found here: c# SortedList<string, TValue>.ContainsKey for successfully added key returns false.
You may want to have a look at the "UPDATE 3" section of my SO question. It appears that the issue was reported to Microsoft in Dec 2012, and closed before the end of january 2013 as "won't be fixed". Additionally it lists a workaround that may be used.
I created an implementation of this recommended workaround, and verified that it fixed the problem that I had encountered. I also just verified that this resolves the issue you reported.
public static void SO_13254153_Question()
{
string x = "\u002D\u30A2"; // or just "-ア" if charset allows
string y = "\u3042"; // or just "あ" if charset allows
var invariantComparer = new WorkAroundStringComparer();
var japaneseComparer = new WorkAroundStringComparer(new System.Globalization.CultureInfo("ja-JP", false));
Console.WriteLine(x.CompareTo(y)); // positive one
Console.WriteLine(y.CompareTo(x)); // positive one
Console.WriteLine(invariantComparer.Compare(x, y)); // negative one
Console.WriteLine(invariantComparer.Compare(y, x)); // positive one
Console.WriteLine(japaneseComparer.Compare(x, y)); // negative one
Console.WriteLine(japaneseComparer.Compare(y, x)); // positive one
}
The remaining problem is that this workaround is so slow it is hardly practical for use with large collections of strings. So I hope Microsoft will reconsider closing this issue or that someone knows of a better workaround.
这篇关于错误字符串中的.NET Framework的比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!