4

Given a case such that:

var collection = myEnumerable as ICollection<MyType>;

What happens under the hood? ICollection has a count property. Does this casting enumerate the enumerable to get the count or does something more involved happen?

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Jamie Dixon
  • 53,019
  • 19
  • 125
  • 162
  • Does this answer your question? [Cannot convert from an IEnumerable to an ICollection](https://stackoverflow.com/questions/8692742/cannot-convert-from-an-ienumerablet-to-an-icollectiont) – Michael Freidgeim May 27 '22 at 08:11
  • Hi @MichaelFreidgeim. I asked this question almost 10 years ago. Thanks for commenting but I no longer have this problem. – Jamie Dixon May 27 '22 at 08:12
  • Sorry for the automatically created unintentional question - the comment should be read as [“Possible duplicate”](https://meta.stackexchange.com/questions/339563/the-auto-comment-does-this-answer-your-question-generated-when-voting-to-clos) – Michael Freidgeim May 27 '22 at 11:52

2 Answers2

9

Nothing happens. If myEnumerable indeed is an ICollection<MyType> collection will contain it. Otherwise it will be null. Simple as that.

Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
  • 1
    Thanks Daniel. How does the count property on ICollection get set? – Jamie Dixon Sep 18 '12 at 09:57
  • It already is there. It doesn't get set. No new instance is created by the cast! – Daniel Hilgarth Sep 18 '12 at 09:59
  • That's good then. I wasn't aware that my IEnumerable was actually an ICollection. Do you have a link that explain this in a bit more detail. Basically I'm dealing with an IEnumerable throughout and I'd rather not enumerate the collection to get the count. Casting to ICollection seems to solve that issue, it just seems a bit odd that it always had the count available in secret. – Jamie Dixon Sep 18 '12 at 10:04
  • 4
    `IEnumerable` is not `ICollection` - it will only cast to `ICollection` and have the count if your instance is actually really an `ICollection` that has been downcasted to `IEnumerable` - if it isnt you will get null, there is no magical conversion going on here. – Richard Friend Sep 18 '12 at 10:05
  • @Jamie Dixon: I don't have a link, sorry. There is no magic here, you are simply using your collection with its base interface `IEnumerable`. Naturally, you than only have the properties of the interface available. BTW: myEnumerable.Count() will *not* enumerate the enumerable if it is an ICollection. – Daniel Hilgarth Sep 18 '12 at 10:06
  • @RichardFriend Thanks for that. The bit I was missing was that the service I'm calling to get the IEnumerable actually creates a list and casts it back to an IEnumerable. Now it makes much more sense. – Jamie Dixon Sep 18 '12 at 10:12
  • 2
    @JamieDixon: A storage location of an interface type does not hold an instance of an interface type (indeed, outside of a few odd cases related to COM interop, there's no such thing as an instance of an interface type). Rather, it holds a reference to an object of some other heap type which implements the interface. Note that every value type has a corresponding heap type to which it may be implicitly converted; storing a struct which implements an interface into a storage location of that interface type will generate a new heap object of the latter type, whose public and private fields... – supercat Sep 18 '12 at 15:34
  • 2
    ...are loaded with the contents of the corresponding struct fields. Storing a reference to a heap object into an interface-type storage location, however, simply causes the storage location to hold a reference to the already-existing object. In that scenario, copying the storage location to one of some other class or interface type will simply cause the latter storage location to hold yet another reference to the same object. – supercat Sep 18 '12 at 15:37
1

Important point:

When ever you cast IEnumerable type object to ICollectionit will be referenced typed.

Like, removing Item from the collection will remove the item from the IEnumerable collection as well.

For Example:

IEnumerable<AnyClass> enumerableObject;

ICollection<AyClass> collectingObject = (ICollection<AnyClass>)enumerableObject;

foreach(var item in collectingObject){

collectingObject.Remove(item);

}

And if you access value of enumerableObject you will find it updated, with all the value removed.

Khawaja Asim
  • 1,327
  • 18
  • 38