Замена List‹IFoo› на List‹Foo, который реализует IFoo›

У меня проблемы с заполнением объекта значениями. Одним из свойств является List<IFoo> foos

позже, когда я захочу заполнить свою модель данными из моей базы данных, я хочу поставить List<Foo> на это свойство.

Я думал, что поскольку Foo правильно реализует интерфейс IFoo, это должно работать (правильно?), но я получаю сообщение об ошибке, говорящее, что я не могу неявно преобразовать List<Foo> в List<IFoo>

Я думаю, что я смотрю мимо чего-то ... Спасибо за помощь заранее


person Pim Schwippert    schedule 24.07.2018    source источник
comment
Есть небольшой пример кода?   -  person Glen Thomas    schedule 24.07.2018
comment
Вы не можете преобразовать List‹Foo› в List‹IFoo› .. но вы можете привести его: foos.Cast<IFoo>().ToList()   -  person richej    schedule 24.07.2018
comment
Вы уверены, что не хотите конвертировать? List<IFoo> fooBar = myFoos.ToList<IFoo>();   -  person JonH    schedule 24.07.2018
comment
Да, конечно, дай мне минутку, и я отредактирую пост.   -  person Pim Schwippert    schedule 24.07.2018
comment
@PimSchwippert - редактировать не нужно, вы можете преобразовать Foos в IFoos, используя ToList<IFoo>()   -  person JonH    schedule 24.07.2018
comment
@JonH У меня есть поле json в моей таблице настроек. это поле настроек может быть всевозможными настройками, поэтому я создал интерфейс ISettings, который ничего не делает, а просто дает мне возможность использовать такие реализации, как мой CustomField, который реализует интерфейс ISetting. Это что-то проясняет?   -  person Pim Schwippert    schedule 24.07.2018
comment
Я вижу, я думаю, что это действительно то, что я ищу. Спасибо! @ДжонХ   -  person Pim Schwippert    schedule 24.07.2018
comment
@PimSchwippert - никто не объясняет это яснее, чем JonSkeet: stackoverflow.com/ questions/8925400/cast-listt-to-listinterface   -  person JonH    schedule 24.07.2018


Ответы (2)


Проще говоря, List<Sheep> не является List<IAnimal>даже если каждый Sheep является IAnimal. Потому что List<IAnimal> позволит мне .Add(new BigBadWolf()), чего List<Sheep> никогда не позволит.

Что вы можете сделать, так это создать новый List<IAnimal> со всеми вашими Sheep, вызвав sheep.ToList<IAnimal>().

person nvoigt    schedule 24.07.2018
comment
Это действительно хороший, простой для понимания пример. - person Erndob; 24.07.2018
comment
Это очень понятно. Однако один вопрос. если у Sheep есть свойство bool IsShaved, а у IAnimal нет, но я знаю, что мой List<IAnimal> в настоящее время содержит только Sheep, могу ли я привести List<IAnimal> обратно к Sheep, чтобы получить доступ к свойству IsShaved? - person Pim Schwippert; 25.07.2018
comment
@PimSchwippert Если ваши животные определенно все овцы, вы можете использовать animalList.Cast<Sheep>(), чтобы получить IEnumerable<Sheep>. Если вы не уверены, есть ли овцы, но хотите сделать что-то со всеми овцами, вы можете использовать animalList.OfType<Sheep>(), чтобы также получить IEnumerable<Sheep>. Не забудьте добавить using System.Linq; поверх вашего файла, если вы это сделаете. - person nvoigt; 25.07.2018
comment
Хорошо, большое спасибо! :) - person Pim Schwippert; 25.07.2018

Данные типы IFoo и Foo:

interface IFoo
{
}

class Foo : IFoo
{
}

Вы можете создать List<IFoo>, заполнить экземплярами Foo и назначить свойство/поле/переменную:

private List<IFoo> foos;

void GetFoos()
{
    foos = new List<IFoo> { new Foo() };
}

Но вы не можете назначить List<Foo> на List<IFoo>:

foos = new List<Foo> { new Foo() };
person Glen Thomas    schedule 24.07.2018