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?

+50
c #
Jan 01 '11 at 10:48
source share
3 answers

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) 
+67
Jan 01 2018-11-11T00:
source share

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();

+19
Jan 01 2018-11-11T00:
source share

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,

+1
Jan 01 '11 at 10:52
source share



All Articles