【发布时间】:2013-03-11 12:17:14
【问题描述】:
在对集合进行排序时,我遇到了 .NET 框架的一个非常奇怪的行为。 这种行为在 .NET 3.5 和 4.0 (but I think I know why) 之间有所不同,但更重要的是(这是我真正关心的问题),同一框架上不同机器的行为不同。
上下文
我正在开发一个依赖于某些第三方软件的软件(在这种情况下是 spring.net,但没关系),并且在某些时候,它正在对一个集合进行排序,该集合的所有项目都“相等” "(比较器总是返回 0)。这不在我的控制之下,如果排序该列表的行为始终保持一致,我会很好。不是。
如何重现
创建一个简单的项目,在 .NET 3.5 中,然后运行下面的代码。 在 3.5 中编译时,行为似乎是一致的,并且集合将被“反转”(结果为 三、二、一)。 现在,请将项目目标更改为 .NET 4 (not 4.5),然后再次运行: 在我的机器上,它不再反转集合(一,二,三),但在其他一些同事的机器上,它确实(三,二,一)!!!我们的设置完全相同...
你能告诉我,在你的机器上,低于 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;
}
}
另外,如果您知道为什么会发生这种情况,请告诉我!
【问题讨论】:
-
如他所说,排序是在第三方代码中完成的,无法更改。
-
供参考:LINQ 的排序是“稳定” - 但不是就地排序
-
MSDN 明确指出 Array.Sort(以及所有使用它的东西)不稳定。那么你想在这里实现什么?如果您无法控制排序,并且文档说不能保证......显然您不应该依赖订单。 (旁注:LINQ 的 OrderBy 确实提供了稳定的排序。)
-
.NET 4 中更改了排序算法。这是一个 GIGO 问题,垃圾进,垃圾出。写一个合适的比较器。
-
正如我所说的,问题是我无法控制其中的任何一个(排序等)。这基本上是 Spring.net 中的一个错误,(幸运的是)在 3.5 下没有引起任何问题,但在切换到 4.0 时开始让我们头疼。似乎最好的做法是修复 spring.net...