Подтвердить что ты не робот

Невозможно преобразовать из IEnumerable <T> в ICollection <T>

Я определил следующее:

public ICollection<Item> Items { get; set; }

Когда я запускаю этот код:

Items = _item.Get("001");

Получаю следующее сообщение:

Error   3   
Cannot implicitly convert type 
'System.Collections.Generic.IEnumerable<Storage.Models.Item>' to 
'System.Collections.Generic.ICollection<Storage.Models.Item>'. 
An explicit conversion exists (are you missing a cast?)

Может кто-нибудь объяснить, что я делаю неправильно. Я очень смущен разница между Enumerable, Collections и использование ToList()

Добавленная информация

Позже в моем коде у меня есть следующее:

for (var index = 0; index < Items.Count(); index++) 

Можно ли определить элементы как IEnumerable?

4b9b3361

Ответ 1

ICollection<T> наследует от IEnumerable<T> так, чтобы назначить результат

IEnumerable<T> Get(string pk)

до ICollection<T> существует два пути.

// 1. You know that the referenced object implements `ICollection<T>`,
//    so you can use a cast
ICollection<T> c = (ICollection<T>)Get("pk");

// 2. The returned object can be any `IEnumerable<T>`, so you need to 
//    enumerate it and put it into something implementing `ICollection<T>`. 
//    The easiest is to use `ToList()`:
ICollection<T> c = Get("pk").ToList();

Второй вариант более гибкий, но имеет гораздо большее влияние на производительность. Другой вариант - сохранить результат как IEnumerable<T>, если вам не нужна дополнительная функциональность, добавленная интерфейсом ICollection<T>.

Комментарий к дополнительной производительности

В цикле у вас

for (var index = 0; index < Items.Count(); index++)

работает с IEnumerable<T>, но неэффективен; каждый вызов Count() требует полного перечисления всех элементов. Либо используйте коллекцию и свойство Count (без скобок), либо преобразуйте их в цикл foreach:

foreach(var item in Items)

Ответ 2

Вы не можете преобразовать непосредственно из IEnumerable<T> в ICollection<T>. Вы можете использовать ToList метод IEnumerable<T>, чтобы преобразовать его в ICollection<T>

someICollection = SomeIEnumerable.ToList();

Ответ 3

В ожидании дополнительной информации по вопросу:

просьба предоставить дополнительную информацию о типе элемента и подписи Get

Две вещи, которые вы можете попробовать:

  • Чтобы вернуть возвращаемое значение _item.Get to (ICollection)
  • во-вторых, использовать _item.Get( "001" ). ToArray() или _item.Get( "001" ). ToList()

Обратите внимание, что вторая приведет к удару производительности для копии массива. Если подпись (тип возврата) Get не является ICollection, то первая не будет работать, если она не IEnumerable, то вторая не будет работать.


После разъяснения вопроса и комментариев я лично объявляю возвращаемый тип _item.Get( "001" ) в ICollection. Это означает, что вам не нужно делать кастинг или преобразование (через ToList/ToArray), что потребует ненужной операции создания/копирования.

// Leave this the same
public ICollection<Item> Items { get; set; }

// Change function signature here:
// As you mention Item uses the same underlying type, just return an ICollection<T>
public ICollection<Item> Get(string value); 

// Ideally here you want to call .Count on the collectoin, not .Count() on 
// IEnumerable, as this will result in a new Enumerator being created 
// per loop iteration
for (var index = 0; index < Items.Count(); index++) 

С уважением,