Почему многомерные массивы C# не реализуют IEnumerable <T>?

64
задан Peter Mortensen 19 May 2018 в 11:12
поделиться

4 ответа

CLR имеет два различных видов массивов: векторы , которые, как гарантируют, будут одномерны с нижней границей 0, и более общие массивы, которые могут иметь ненулевые границы и разряд кроме 0.

раздел From 8.9.1 из спецификации CLI:

Кроме того, созданный вектор с типом T элемента, реализует интерфейс System.Collections.Generic.IList<U> (В§8.7), где U: = T.

я должен сказать, что это кажется довольно странным мне. Учитывая, что это уже реализует IEnumerable, я не вижу, почему это не должно реализовывать IEnumerable<T>. Это не имело бы столько же смысла реализовать IList<T>, но простой универсальный интерфейс будет прекрасен.

, Если Вы хотите это, Вы могли бы или звонить Cast<T> (если Вы используете.NET 3.5), или запишите свой собственный метод для итерации через массив. Чтобы постараться не бросать, необходимо было бы записать собственный метод, который нашел более низкие / верхние границы каждого размера и выбрал вещи тот путь. Не ужасно приятный.

47
ответ дан Jon Skeet 24 November 2019 в 16:00
поделиться

Многомерные массивы не массивы в целях иерархии наследования. Они - абсолютно отдельный тип. Кроме того, этот тип не имеет никакой хорошей поддержки со стороны платформы для двух возможных причин:

  • Это не действительно настолько полезно. Единственное реальное использование для многомерных массивов является матрицами. Для почти чего-либо еще, лучше подходят другие структуры данных (например, зубчатые массивы).
  • Это не тривиально для разработки универсальных, полезных методов для этих структур.

В случае IEnumerable, как это должно было быть реализовано, т.е. в котором порядке должны быть перечислены элементы? Нет никакого порядка, свойственного от многомерных массивов.

4
ответ дан Konrad Rudolph 24 November 2019 в 16:00
поделиться

Зубчатые массивы не поддерживают IEnumerable<int> также, потому что многомерные структуры не являются действительно массивом типа, они - массив массива типа:

int[] singleDimensionArray = new int[10];
int[][] multiJagged = new int[10][];

Debug.WriteLine(singleDimensionArray is IEnumerable<int>);
Debug.WriteLine(multiJagged is IEnumerable<int[]>);
Debug.WriteLine(singleDimensionArray is IEnumerable);
Debug.WriteLine(multiJagged is IEnumerable);

Печать, верная, верная, верная, верная.

Примечание : int[,] не IEnumerable<int[]>, это по причинам, определенным в другом ответе, а именно, нет никакого универсального способа знать который размер выполнить итерации. С зубчатыми массивами нет такого же количества комнаты для интерпретации, потому что синтаксис довольно соглашается с ним являющийся массивом массивов.

0
ответ дан Matthew Scharley 24 November 2019 в 16:00
поделиться

Есть обходной путь: вы можете преобразовать любой многомерный массив в IEnumerable

public static class ArrayExtensions
{
    public static IEnumerable<T> ToEnumerable<T>(this Array target)
    {
        foreach (var item in target)
            yield return (T)item;
    }
}
14
ответ дан 24 November 2019 в 16:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: