Unable to convert from IEnumerable <T> to ICollection <T>
I have defined the following:
public ICollection<Item> Items { get; set; } When I run this code:
Items = _item.Get("001"); I get the following message:
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?) Can someone explain what I'm doing wrong. I am very confused about the difference between Enumerable, Collections and using ToList ()
Information Added
Later in my code, I have the following:
for (var index = 0; index < Items.Count(); index++) Is it possible to define elements as IEnumerable?
ICollection<T> inherits from IEnumerable<T> so as to assign a result
IEnumerable<T> Get(string pk) There are two ways to 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(); The second option is more flexible, but has a much greater impact on performance. Another option is to save the result as IEnumerable<T> if you do not need additional functionality added by the ICollection<T> interface.
Additional Performance Commentary
In the loop you
for (var index = 0; index < Items.Count(); index++) works with IEnumerable<T> but is inefficient; each call to Count() requires a complete listing of all the elements. Either use the collection and the Count property (without parentheses), or convert them to a foreach loop:
foreach(var item in Items) You cannot convert directly from IEnumerable<T> to ICollection<T> . You can use the ToList method of IEnumerable<T> to convert it to ICollection<T>
someICollection = SomeIEnumerable.ToList();
Awaiting further information on:
please provide additional information on the type of the element and the signature Get
Two things you can try:
- To return the return value _item.Get to (ICollection)
- secondly, use _item.Get ("001"). ToArray () or _item.Get ("001"). ToList ()
Note that the second will lead to a performance hit for the copy array. If the signature (return type) of Get is not an ICollection, then the first will not work; if it is not IEnumerable, then the second will not work.
After clarifying the question and commenting, I personally declare the _item.Get ("001") return type in ICollection. This means that you do not need to do casting or conversion (via ToList / ToArray), which will require an unnecessary create / copy operation.
// 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++) Respectfully,