Почему dotnet 1.1 не может быть отключен после ArrayList.GetRange?

Я хотел бы создать массив из диапазона значений в ArrayList, но получаю сообщение об ошибке «По крайней мере один элемент в исходном массиве не может быть приведен к целевому типу массива».

Почему следующее должно потерпеть неудачу, и что бы вы сделали вместо этого?

int[] ints = new int[] { 1, 2, 3 };
ArrayList list = ArrayList.Adapter(ints);
int[] mints = (int[])list.GetRange(0, 2).ToArray(typeof(int));

person stovroz    schedule 19.02.2009    source источник
comment
попробуйте это с типом, не являющимся значением (например, строки), это может быть проблема с боксом   -  person ShuggyCoUk    schedule 20.02.2009


Ответы (4)


Это известная ошибка в .NET 1.1, исправленная в .NET 2.0.

В этом выпуске нарушено поведение GetRange. Если вы попытаетесь перечислить содержимое возвращаемого значения, используя ToArray() без параметров для экземпляра оболочки ArrayList, возвращаемого GetRange, вы увидите, что оно содержит нулевые ссылки и другие несогласованные значения.

См. сообщения от декабря 2004 г. здесь и здесь, в блоге команды BCL.

person Jérôme Laban    schedule 21.02.2009
comment
Ссылки мертвы. Не могу найти эти страницы даже в WebArchive. - person Кое Кто; 09.10.2020

Это прекрасно работает в DotNet 2.0, поэтому я предлагаю начать со сравнения дизассемблированного кода Framework, чтобы увидеть, в чем разница.

В 2.0 вызов ArrayList.Adapter() возвращает ArrayList.IListWrapper (который наследуется от ArrayList), который просто обертывает IList (в вашем случае массив типа int[]). Вызов ToArray для IListWrapper вызывает IList.CopyTo для базового массива.

Очевидно, что в 1.1 это должно быть реализовано по-другому, потому что то, как это настроено в 2.0, не может дать сбой.

person snarf    schedule 19.02.2009

Обычно это должно просто работать:

(int[])list.GetRange(0, 2).ToArray(typeof(int));

Поскольку GetRange просто возвращает новый ArrayList.

Вы уверены, что ваш ArrayList содержит только целые числа и ничего больше?

Я не могу проверить это в .NET 1.1, но я предполагаю, что: - ваш список массивов содержит элементы другого типа, кроме int. - причиной проблемы является метод ArrayList.Adapter.

Кроме того, почему бы вам не инициализировать ArrayList следующим образом:

ArrayList l = new ArrayList ( new int[] {0, 1, 2, 3, 4, 5});

?

person Frederik Gheysels    schedule 19.02.2009
comment
Я думаю, дело в том, что опубликованный код не должен давать сбоев, а тот факт, что это происходит, указывает на большую вероятность необъяснимых исключений в различных обстоятельствах. - person snarf; 20.02.2009

Если вы умеете работать с массивами, возможно, просто Array.Copy:

    int[] ints = new int[] { 1, 2, 3 };
    int[] mints = new int[2];
    Array.Copy(ints, 0, mints, 0, 2);

В качестве альтернативы, похоже, вам придется создать массив и выполнить цикл/приведение.

(для информации, он отлично работает "как есть" на 2.0, хотя вместо этого вы бы использовали List<int>)

person Marc Gravell    schedule 19.02.2009