C# .NET3.5和.NET4.0之间排序的差异

C# .NET3.5和.NET4.0之间排序的差异,c#,.net,.net-4.0,.net-4.5,C#,.net,.net 4.0,.net 4.5,在对集合进行排序时,我遇到了.NET framework的一个非常奇怪的行为。 这种行为在.NET 3.5和4.0()之间有所不同,但更重要的是(这是我在这里真正关心的问题),在同一框架上的不同机器上,这种行为是不同的 上下文 我正在开发一个依赖于第三方软件的软件(本例中是spring.net,但这并不重要),在某个时候,它正在对一个集合进行排序,该集合的所有项都是“相等的”(比较器总是返回0)。这是而不是在我的控制下,如果排序列表的行为总是一致的,我会很好地处理它。不是 如何繁殖 在.NET

在对集合进行排序时,我遇到了.NET framework的一个非常奇怪的行为。 这种行为在.NET 3.5和4.0()之间有所不同,但更重要的是(这是我在这里真正关心的问题),在同一框架上的不同机器上,这种行为是不同的

上下文 我正在开发一个依赖于第三方软件的软件(本例中是spring.net,但这并不重要),在某个时候,它正在对一个集合进行排序,该集合的所有项都是“相等的”(比较器总是返回0)。这是而不是在我的控制下,如果排序列表的行为总是一致的,我会很好地处理它。不是

如何繁殖 在.NET 3.5中创建一个简单的项目,,并运行下面的代码。 在3.5中编译时,行为似乎是一致的,集合将被“反转”(结果为3,2,1)。 现在,请将项目目标更改为.NET 4(不是4.5),然后再次运行: 在我的机器上,它不再反转集合(一、二、三),但在其他同事的机器上,它反转集合(三、二、一)!!!我们有完全相同的设置

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

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

概念证明
还有,如果你知道为什么会这样,请告诉我

ArrayList.sort()完成的排序不稳定,因此无法预测“相同”项的排序顺序

此外,由于ArrayList.Sort()可能会使用随机机制为其快速排序算法选择轴,因此相同的项目可能会在不同的PC上,甚至在同一台PC上进行不同的排序

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

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


它似乎在为.Net 4.5选择一种完全不同的排序算法。

正如他所说,排序是在第三方代码中进行的,不能更改。信息:LINQ的排序是“稳定的”-但不是一个就地的sortMSDN清楚地表明数组。sort(以及使用它的所有东西)是不稳定的。那么你想在这里实现什么呢?如果你不能控制分类,而医生说不能保证。。。很明显,你不应该依赖订单。(旁注:LINQ的OrderBy确实提供了稳定的排序。)排序算法在.NET4中更改。这是GIGO的问题,垃圾进来,垃圾出去。写一个合适的比较器。正如我说的,问题是我不能控制任何一个(排序等)。这基本上是Spring.net中的一个bug,(幸运的是)在3.5以下时没有引起任何问题,但在切换到4.0时开始让我们头疼。似乎最好的做法是修复spring.net…可能就是这样:我们机器之间的区别在于我有VS 2012,而其他用户没有(只有2010年)。显然,安装VS 2012会替换.NET 4的一些DLL,并且可能会将排序算法更改为您前面提到的内省软件。谢谢感谢您添加Reflector(ed)代码,显示内省排序与DepthLimitedQuickSort。这对我帮助很大。
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;
    }
}
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);
    }
}