我有一个项目针对.NET 4.0中下面的测试:
[TestFixture]
public class Donkey
{
[Test]
public void TestListSorting()
{
var expected = new[]
{
MockRepository.GenerateStub<IComparable>(),
MockRepository.GenerateStub<IComparable>()
};
var sorted = new List<IComparable>(expected);
CollectionAssert.AreEqual(expected, sorted);
sorted.Sort();
CollectionAssert.AreEqual(expected, sorted);
}
}
如果我只用.NET 4.0安装在计算机上运行它,它失败。 如果我只用.NET 4.5安装在计算机上运行它,它传递。
我假设在.NET 4.5的执行Sort
已经改变排序的对象,每个返回列表时维持秩序0
距离CompareTo
。
现在,抛开这个测试有明显的精神错乱。 我知道这是疯狂的依赖于这种行为。
当然这是一个重大更改? 它不是对上市这个网页约.NET 4.0和4.5之间的兼容性。
是否有一个原因? 我缺少的东西吗? 难道还有其他的网页,其中显示实际的重大更改? 我是不是应该有一个坐下,别恐慌?
我已经回答了类似的问题之前,这个。 排序方法4.5和4.0之间变化,从一个快速排序到内省排序 。
它实际上是快,但它仍然不是一个稳定的排序1,即一个具有利用保护等项目的顺序每次执行相同的输出。 由于没有实施List.Sort
是一个稳定的排序,我不认为你已经运行上述足够的时间单元测试有两种运行时它的错误?
我试着用等效代码,并且有时返回0列表顺序是保留的,有时不是,在这两个.NET 4.5和.NET 3.5的比较器复制它自己。
即使它确实改变从稳定到不稳定的那种类型, 它不是一个重大更改 。 的类型中使用的排序和精确的输出是不合同的一部分List.Sort
。 所有这些方法合同,保证是你的项目将根据所使用的比较器在有序。
有趣的是,虽然,因为[MSDN文档(http://msdn.microsoft.com/en-us/library/b0zbh7b6.aspx)仍然表示,它使用快速排序(通过`Array.Sort`),但是这是不,如果你要一步通过.NET参考源的情况。
1 使用的混合的定义QuickSort
和HeapSort
,它应该是一个不稳定的排序。 即使是大卫·马瑟,在算法州的设计师他的论文 :
内省排序,快速排序一样,也不稳定-不保留相当于元素的顺序-所以仍然需要有一个稳定的排序例程一个独立的要求。
该规范对List.Sort
说,使用的排序是不稳定的,因此可能无法维持相等的元素的顺序; 它不等于指定特定元素重新排序,所以你不能真正把这种变化的重大更改。
作为@Rawling说,看看该文件Sort()
此实现执行不稳定排序; 也就是说,如果两个元素相等,它们的顺序可能不会被保留。
所以,你想测试的东西是明确记录为不确定。 这不是一个重大更改。
我看不出有什么变化。 正如其他人已经写,这两个版本的执行不稳定排序。 这意味着,你不能依赖于作为比较平等要素的顺序。 他们的订单可能会或排序过程中可能不会改变。 这当然不是一个重大更改。
参见: 列表的文档<T>的.sort
从MSDN
此实现执行不稳定排序; 也就是说,如果两个元素相等,它们的顺序可能不保留
不像顺序是可靠的,因此测试是无效的。 此外,你为什么测试Sort
反正方法? 似乎是不必要的测试给我。
这样的问题经常拿出新的框架版本。 还有一些为3.5→4.0过渡这里和这里 。
适用版本的这个特定的变化,所不同的出现已经蒙山数组或List<>
两个元件的,作为问题显示。 另一简单的实例是:
using System;
using System.Linq;
namespace SortTest
{
static class Program
{
static void Main()
{
var arr = new[] { new { Name = "Mary", Age = 17, }, new { Name = "Louise", Age = 17, }, };
Array.Sort(arr, (x, y) => x.Age.CompareTo(y.Age));
Console.WriteLine(string.Join(",", arr.Select(x => x.Name)));
}
}
}
在.NET 4.0中打印Louise,Mary
。 这些元素被交换。 然而,随着.NET 4.5它打印Mary,Louise
。 需要注意的是两个女孩有相同的年龄。
List<>.Sort
实例方法和Array.Sort
静态方法都记录为非稳定排序。 他们是自由的,他们希望的任何命令离开等于“大小”的元素。 所以,你的代码不能做出什么顺序等同的元素进来任何假设。
相比之下,LINQ的的OrderBy
方法执行一个稳定的排序。 所以
var ordered = arr.OrderBy(x => x.Age);
要求 不换玛丽·路易丝,因为它们具有相同的Age
。