Не удается преобразовать тип IEnumerable в коллекцию ICollection


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

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?)

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

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

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

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

Я был бы в порядке, чтобы определить элементы как Интерфейс IEnumerable?

3 64

3 ответа:

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)

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

someICollection = SomeIEnumerable.ToList();

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

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

две вещи, которые вы можете попробовать являются:

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

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


после вашего разъяснения на вопрос и в комментариях, я бы лично объявить возвращаемый тип _item.Получить ("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++) 

С уважением,