Почему List.AddRange принимает T [], но не принимает IEnumerable <T> - PullRequest
0 голосов
/ 10 сентября 2018

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

Я написал этот метод:

private void AddItems<T>(T[] items) where T : SomeClass
    {
        if (items != null)
        {
            someList.AddRange(items);
        }
    }

это работает нормально, однако мой вопрос: почему это так:

private void AddItems<T>(IEnumerable<T> items) where T : SomeClass
    {
        if (items != null)
        {
            someList.AddRange(items);
        }
    }

не работает?

В последнем примере выдается эта ошибка: «Аргумент 1: невозможно преобразовать из System.Collections.Generic.IEnumerable<T> в System.Collections.Generic.IEnumerable<SomeClass>»

List<SomeClass> someList = new List<SomeClass>();

ошибка

1 Ответ

0 голосов
/ 10 сентября 2018

Это связано с тем, как работают массивы и генерики. У вас есть переменная, набранная так:

IEnumerable<SomeSpecificClass>

Откуда вы знаете, что SomeSpecificClass всегда наследуется от SomeClass. Вы хотите добавить все элементы в этой последовательности в List<SomeClass>, используя AddRange(). Но List<SomeClass>.AddRange является конкретным; он хочет точно IEnumerable<SomeCass>, и вы не можете напрямую разыграть от IEnumerable<SomeSpecificClass> до IEnumerable<SomeClass>. Вы можете исправить это с помощью простого Cast<T>():

someList.AddRange(items.Cast<SomeClass>());

Теперь вопрос в том, почему массив работает, и ответ таков, что массивы являются особенными в этом смысле. Они больше, чем просто дженерики. Вы можете напрямую привести SomeSpecificClass[] к SomeClass[], а поскольку SomeClass[] реализует IEnumerable<SomeClass>, все уже в порядке.

...