C# - странное поведение с ToList() и ToArray()

Я заметил странное поведение при использовании комбинации ToList() и ToArray() в C# (с использованием фейерверка.NET 4.5.2).

Дана следующая тестовая программа:

int[] array = { 5, 1, -10, 667, 4 };
SorteerBib<int>.SelectionSort(array, Comparer<int>.Default);
Console.Out.WriteLine("Result - WRONG!");
for (int i = 0; i < array.Length; i++)
{
    Console.Out.Write(array[i] + " ");
    Console.Out.WriteLine();
}
Console.ReadKey();

Класс SorteerBib состоит из 2 методов:

class SorteerBib<T>
{
    public static IList<T> SelectionSort(IList<T> list, IComparer<T> comparer)
    {
        for (int i = 0; i < list.Count - 1; i++)
        {
            int minIndex = i;
            for (int j = i + 1; j < list.Count; j++)
            {
                if (comparer.Compare(list[j], list[minIndex]) < 0)
                {
                    minIndex = j;
                }
            }
            T temp = list[i];
            list[i] = list[minIndex];
            list[minIndex] = temp;
        }

        Console.Out.WriteLine("Result SelectionSort IList - OK");
        for (int i = 0; i < list.Count; i++)
        {
            Console.Out.Write(list[i]+" ");
            Console.Out.WriteLine();
        }
        return list;
    }

    public static void SelectionSort(T[] array, IComparer<T> comparer)
    {
        // DOES NOT WORK, WHY?
        array = ((SelectionSort(array.ToList(), comparer)).ToArray());

        Console.Out.WriteLine("Result SelectionSort Array - OK");
        for (int i = 0; i < array.Length; i++)
        {
            Console.Out.Write(array[i] + " ");
            Console.Out.WriteLine();
        }
    }
}

Ошибка лежит в первой строке второго метода:

array = ((SelectionSort(array.ToList(), comparer)).ToArray());

В методе void массив сортируется после этой строки, но как только мы вернемся к основной программе, сортировка исчезнет.

Замена этой строки следующими строками, однако, устраняет эту проблему:

IList<T> temp = SelectionSort(array.ToList<T>(), comparer);
for (int i = 0; i < array.Length; i++) {
    array[i] = temp[i];
}

Кто-нибудь может объяснить это непредсказуемое поведение? Спасибо заранее!

1 ответ

Решение

Вы передаете массив без ключевого слова ref, а затем измените его ссылку, выполнив:

array = ((SelectionSort(array.ToList(), comparer)).ToArray());

Поскольку ключевое слово ref не используется, изменение применяется только в функции.

Исправление будет заключаться в добавлении ключевого слова ref:

public static void SelectionSort(ref T[] array, IComparer<T> comparer)

Кстати, лучший подход будет сортировать ICollection<T> или IEnumerable<T> вместо.

Другие вопросы по тегам