c# .net .net-4.0 .net-4.5

c# - Diferencia en la clasificación entre.NET 3.5 y.NET 4.0



.net-4.0 .net-4.5 (1)

Me he topado con un comportamiento muy extraño de .NET Framework (s) al ordenar una colección. Este comportamiento es diferente entre .NET 3.5 y 4.0 ( pero creo que sé por qué ), pero lo más importante (y esa es mi verdadera preocupación aquí), el comportamiento es diferente en diferentes máquinas en el mismo marco .

Contexto

Estoy trabajando en un software que depende de un software de terceros (Spring.net en este caso, pero no importa), y en algún momento, está ordenando una colección que tiene todos sus elementos "iguales" (el comparer siempre devuelve 0). Esto NO está bajo mi control y estaría muy bien si el comportamiento de ordenar esa lista siempre fuera consistente. No es.

Cómo reproducir

Cree un proyecto simple, en .NET 3.5 , y ejecute el código a continuación. Cuando se compila en 3.5, el comportamiento parece ser consistente, y la colección se "revertirá" (sale como Tres, Dos, Uno ). Ahora, cambie el objetivo del proyecto a .NET 4 ( no 4.5 ) y ejecútelo de nuevo: en mi máquina, ya no revierte la colección (Uno, Dos, Tres), pero en alguna otra máquina de colegas lo hace (Tres dos uno)!!! Tenemos exactamente la misma configuración ...

¿Puede decirme, en su máquina, en 4.0, cuál es? ¿Invertido o no invertido?

Estoy tratando de evaluar si mi configuración es correcta o no.

Prueba de concepto

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; } }

Además, si tiene alguna idea de por qué sucede esto, ¡por favor hágamelo saber!


El orden hecho por ArrayList.Sort () no es estable, por lo tanto, no puede predecir el orden en que se ordenarán los elementos "idénticos".

Además, debido a que ArrayList.Sort () puede usar un mecanismo aleatorio para seleccionar el pivote para su algoritmo QuickSort, elementos idénticos pueden clasificarse de manera diferente en diferentes PC o incluso en la misma PC.

[EDIT: no puedo encontrar ninguna evidencia de que se haya elegido un pivote aleatorio en las implementaciones actuales, pero el ordenamiento de las matrices sigue siendo inestable. Supongo que la aleatoriedad proviene de la implementación del código nativo de Quicksort en TrySZSort() que es lo que probablemente se llame.]

También por cuestiones de interés, Reflector muestra este código en ArrayList.Sort () (si profundiza un poco):

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); } }

que parece estar seleccionando un algoritmo de ordenamiento completamente diferente para .Net 4.5.