Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does ICollection not contain an Add method? [closed]

As in the title, does anyone know why the ICollection interface does not contain an Add method? It seems very odd that the generic version, ICollection<T>, has an Add but ICollection does not. Anyone with deeper knowledge on this would be really helpful.

As to why I care- unfortunately the developers who build SharePoint have never learned about generics, so every single collection in the API is a a non-generic collection based off of ICollection. I'd like to attach several extension methods to ICollection that involve adding to the collection, among other things, but this seems to be impossible (at least not possible without reflection).

EDIT:

Quite a few people are speculating the reason is because ICollection.Add would require an Object, and thus wouldn't be typesafe. This isn't the case. IList has an Add method that takes an Object. You simply need to do a typecheck and a cast in a method that takes Object.

The argument that an array implements ICollection and therefore it can't have an Add also doesn't hold water. If ICollection had an Add method, it would just need to be explicitly implemented on arrays and throw an Exception (as many of the methods arrays implement currently do).

I was really hoping someone had a reference to an explanation by one of the designers.

like image 653
MgSam Avatar asked Jul 27 '12 14:07

MgSam


2 Answers

To me it seems the naming of the interfaces is confusing the expectations. ICollection and ICollection<T> aren't even in the same inheritance chain - most collections just simply implement both.

The documentation states what the interface does, so taking this alone, one wouldn't expect Add to exist:

Defines size, enumerators, and synchronization methods for all nongeneric collections.

What do I think? Personally I think it's either a straight naming gaff or the second time around (when introducing the generic interfaces) the designers chose to put Add in ICollection<T> because this time it was more common to need it.

The IList has Add and inherits ICollection whereas the IList<T> doesn't have Add and inherits ICollection<T>, which as Add.

Chalk it up to evolution / maturing of the type hierarchy design.


As for the extension methods, you can do something like:
public static void AnotherMethod<T>(this ICollection<T> collection, T item) { }

And use it thus:

ICollection<string> s;
s.AnotherMethod("");
like image 98
Adam Houldsworth Avatar answered Oct 05 '22 11:10

Adam Houldsworth


ICollection can be anything. It could be something that is nothing but enumerable. There is no reason there should be an Add method, or indeed a Remove. If you look at the interface more closely, it's pretty much read-only. You can see how many elements there are, and you can enumerate them. That's it. This makes perfect sense, in an abstract kind of way.

When we get to ICollection<T>, we are now being very specific. We know exactly what kind of object it holds and therefore we can:

  • Add new elements of <T>.
  • Search for them using an IEquitable kind of interface.
  • Remove them, using the same methodology.

In essence, the difference is that ICollection<T> is somewhat concrete.

like image 37
Moo-Juice Avatar answered Oct 05 '22 12:10

Moo-Juice