Почему я не могу использовать AddRange для добавления элементов подклассов?

StackOverflow https://stackoverflow.com/questions/1072581

Вопрос

У меня два класса....Parcel и FundParcel... и я пытаюсь преобразовать IEnumerable подтипа в IList супертипа....

public class FundParcel : Parcel
{
  /* properties defined here */
}

public class Parcel
{
  /* properties defined here */
}

Они используются в другом классе в методе следующим образом:

private IList<Parcel> ExtractParcels(IEnumerable<FundParcel> fundParcels)
{
    var parcels = new List<Parcel>();

    foreach (var fp in fundParcels)
        parcels.Add(fp);

    return parcels;
}

Чего я не понимаю, так это почему оператор foreach нельзя свести к:

parcels.AddRange(fundParcels);

В основном я получаю сообщение об ошибке: «Тип аргумента 'System.Colection.Generic.IEnumerable<FundParcel>' is not assignable to parameter type 'System.Collections.Generic.IEnumerable<Parcel>'"

Но если это так, то я не понимаю, почему посылки.Добавить работает...

Мне кажется, что весь метод следует заменить строкой:

return (List<Parcel>)fundParcels;

...или, может быть, этот метод можно вообще отказаться, поскольку подтипы должны заменять свои супертипы..

Может ли кто-нибудь объяснить, в чем дело с AddRange в этом случае и почему в этом случае может потребоваться цикл for?

Это было полезно?

Решение

Это ТАК вероятно, ответит на ваш вопрос, а также укажет вам ссылки на предстоящую версию C# 4.0, которая в определенной степени будет поддерживать ко-/контра-вариантность.

Другие советы

Рассмотрим этот код:

void AddParcelToParcelList(List<Parcel> parcels) {
  parcels.add(new Parcel());
}

List<FundParcel> fundParcels = new List<FundParcels>();
AddParcelToParcelList(fundParcels);

Если контейнеры унаследованных классов также унаследованы от контейнеров базовых классов, приведенный выше код будет действительным и создаст случай, когда список унаследованного класса содержит объект базового класса.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top