. net 3.5和.net 4.0在排序方面的差异

本文关键字:net 方面 排序 | 更新日期: 2023-09-27 18:03:14

我遇到过。net框架的一个非常奇怪的行为,当排序一个集合时。这种行为在。net 3.5和。net 4.0之间是不同的(但我想我知道为什么),但更重要的是(这是我在这里真正关心的),在同一框架上的不同机器上的行为是不同的

<<h2>上下文/h2>

我正在开发一个依赖于第三方软件的软件(spring.net在这种情况下,但这并不重要),在某些时候,它正在排序一个集合,它的所有项目"相等"(比较器总是返回0)。这是不是在我的控制下,如果排序列表的行为总是一致的,我会很好。它不是。

如何复制

在。net 3.5中创建一个简单的项目,并运行下面的代码。当在3.5中编译时,行为似乎是一致的,并且集合将被"反转"(它出现为Three, Two, One)。现在,请将项目目标更改为。. NET 4 (不是4.5),并再次运行:在我的机器上,它不再反转集合(One, Two, Three),但在其他一些同事的机器上,它可以(Three, Two, One)!!我们有完全相同的设置…

你能告诉我,在你的机器上,在4.0下,它是哪个吗?反转还是不反转?

我正在试着评估我的设置是否正确。

概念证明

class Program
{
    static void Main()
    {
        var collection = new ArrayList
        {
            "One",
            "Two",
            "Three",
        };
        // It should in any case write One, Two, Three
        Console.Out.WriteLine("Before sort: ");
        foreach (string item in collection)
        {
            Console.Out.WriteLine("'t"+item);
        }
        collection.Sort(new OrderComparator());
        // In .NET 3.5, it will write Three, Two, One
        // In .NET 4, it will sometimes write Three, Two, One, sometimes One, Two, Three: what is it for you?
        Console.Out.WriteLine("After sort: ");
        foreach (string item in collection)
        {
            Console.Out.WriteLine("'t" + item);
        }
        Console.Out.WriteLine("--end--");
        Console.Read();
    }
}
public class OrderComparator : IComparer
{
    public virtual int Compare(object o1, object o2)
    {
        return 0;
    }
}

另外,如果你知道为什么会发生这种情况,请告诉我!

. net 3.5和.net 4.0在排序方面的差异

由ArrayList.Sort()完成的排序是不稳定的,因此你不能预测"相同"项的排序顺序。

此外,因为ArrayList.Sort()可能使用随机机制来选择快速排序算法的枢轴,相同的项可能在不同的PC上排序不同,甚至在同一台PC上。

[编辑:我找不到在当前实现中选择随机枢轴的任何证据,但数组排序仍然不稳定。我猜随机性来自TrySZSort()的本机代码快速排序实现,这可能被称为。]

同样出于兴趣,Reflector在ArrayList.Sort()中显示了这段代码(如果您深入研究一下):

internal void Sort(int left, int length)
{
    if (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5)
    {
        this.IntrospectiveSort(left, length);
    }
    else
    {
        this.DepthLimitedQuickSort(left, (length + left) - 0x1, 0x20);
    }
}

,它似乎为。net 4.5选择了一个完全不同的排序算法。