gpt4 book ai didi

c# - 为什么默认的字符串比较器无法保持传递一致性?

转载 作者:行者123 更新时间:2023-11-30 18:15:47 25 4
gpt4 key购买 nike

我知道这个问题has been noted before ,或多或少简洁,但我仍然创建了这个新线程,因为我在编写单元测试时再次遇到了这个问题。

默认字符串比较(即我们通过 string.CompareTo(string)Comparer<string>.DefaultStringComparer.CurrentCulturestring.Compare(string, string) 等获得的依赖于文化的区分大小写的比较)在字符串包含连字符(或减号)时违反传递性标志,我说的是普通的 U+002D 字符)。

这是一个简单的重现:

static void Main()
{
const string a = "fk-";
const string b = "-fk";
const string c = "Fk";

Console.WriteLine(a.CompareTo(b)); // "-1"
Console.WriteLine(b.CompareTo(c)); // "-1"
Console.WriteLine(a.CompareTo(c)); // "1"

var listX = new List<string> { a, b, c, };
var listY = new List<string> { c, a, b, };
var listZ = new List<string> { b, c, a, };
listX.Sort();
listY.Sort();
listZ.Sort();
Console.WriteLine(listX.SequenceEqual(listY)); // "False"
Console.WriteLine(listY.SequenceEqual(listZ)); // "False"
Console.WriteLine(listX.SequenceEqual(listZ)); // "False"
}

在上半部分,我们看到了传​​递性是如何失败的。 a小于 b , 和 b小于 c , 然而a不能小于 c .

这违背了 documented behavior Unicode 排序规则的声明:

... for any strings A, B, and C, if A < B and B < C, then A < C.

现在用 a 对列表进行排序, bc就像试图对 "Rock", "Paper" and "Scissors" 的手进行排名一样在著名的不及物游戏中。不可能完成的任务。

我上面的代码示例的最后一部分显示排序结果取决于元素的初始顺序(并且列表中没有两个比较“相等”的元素(0))。

Linq 的 listX.OrderBy(x => x)当然也会受到影响。这应该是一个稳定的排序,但在排序包含 a 的集合时会得到奇怪的结果, bc连同其他字符串。

我用 all 试过 CultureInfo s 在我的机器上(因为这是一种依赖文化的类型),包括“不变文化”,每个人都有同样的问题。我在 .NET 4.5.1 运行时试过这个,但我相信旧版本有同样的错误。

结论:在 .NET 中使用默认比较器对字符串进行排序时,如果某些字符串包含连字符,则结果不可预测。

.NET 4.0 中引入了哪些更改导致了此行为?

已经观察到这种行为在不同版本的平台上是不一致的:在 .NET 3.5 中,可以可靠地对带有连字符的字符串进行排序。在所有版本的框架中,调用 System.Globalization.CultureInfo.CurrentCulture.CompareInfo.GetSortKey提供独特的 DeyData对于这些字符串,为什么它们没有正确排序?

最佳答案

Microsoft Connect Discussion下面是一些解决方法的代码:

static int CompareStringUsingSortKey(string s1, string s2)
{
SortKey sk1 = CultureInfo.InvariantCulture.CompareInfo.GetSortKey(s1);
SortKey sk2 = CultureInfo.InvariantCulture.CompareInfo.GetSortKey(s2);
return SortKey.Compare(sk1, sk2);
}

关于c# - 为什么默认的字符串比较器无法保持传递一致性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47714877/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com