Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does an ICollection<T> have an order?

Following the rules that a public APIs should never return a list, i'm blinding converting all code that returned lists, to return ICollection<T> instead:

public IList<T> CommaSeparate(String value) {...}

becomes

public ICollection<T> CommaSeparate(String value) {...}

And although an ICollection has a Count, there is no way to get items by that index.

And although an ICollection exposes an enumerator (allowing foreach), i see no guarantee that the order of enumeration starts at the "top" of the list, as opposed to the "bottom".

i could mitigate this by avoiding the use of ICollection, and instead use Collection:

public Collection<T> Commaseparate(String value) {...}

This allows the use of an Items[index] syntax.

Unfortunately, my internal implementation constructs an array; which i can be cast to return IList or ICollection, but not as a Collection.

Is there a ways to access items of a collection in order?

This begs the wider question: Does an ICollection even have an order?


Conceptually, imagine i want to parse a command line string. It is critical that the order of items be maintained.

Conceptually, i require a contract that indicates an "ordered" set of string tuples. In the case of an API contract, to indicate order, which of the following is correct:

IEnumerable<String> Grob(string s)

ICollection<String> Grob(string s)

IList<String> Grob(string s)

Collection<String> Grob(string s)

List<String> Grob(string s)
like image 311
Ian Boyd Avatar asked Jan 05 '12 21:01

Ian Boyd


People also ask

What is the difference between ICollection and list?

ICollection<T> is an interface, List<T> is a class.

Which interface does ICollection T inherit from?

Generic. ICollection<T> interface. The ICollection interface extends IEnumerable; IDictionary and IList are more specialized interfaces that extend ICollection. An IDictionary implementation is a collection of key/value pairs, like the Hashtable class.

What is the difference between ICollection and IEnumerable?

IEnumerable has one property: Current, which returns the current element. ICollection implements IEnumerable and adds few additional properties the most use of which is Count. The generic version of ICollection implements the Add() and Remove() methods.


4 Answers

The ICollection<T> interface doesn't specify anything about an order. The objects will be in the order specified by the object returned. For example, if you return the Values collection of a SortedDictionary, the objects will be in the the order defined by the dictionary's comparer.

If you need the method to return, by contract, a type whose contract requires a certain order, then you should express that in the method's signature by returning the more specific type.

Regardless of the runtime type of the object returned, consider the behavior when the static reference is IList<T> or ICollection<T>: When you call GetEnumerator() (perhaps implicitly in a foreach loop), you're going to call the same method and get the same object regardless of the static type of the reference. It will therefore behave the same way regardless of the CommaSeparate() method's return type.

Additional thought:

As someone else pointed out, the FXCop rule warns against using List<T>, not IList<T>; the question you linked to is asking why FXCop doesn't recommend using IList<T> in place of List<T>, which is another matter. If I imagine that you are parsing a command-line string where order is important, I would stick with IList<T> if I were you.

like image 87
phoog Avatar answered Oct 11 '22 03:10

phoog


ICollection does not have a guaranteed order, but the class that actually implements it may (or may not).

If you want to return an ordered collection, then return an IList<T> and don't get too hung up on FxCop's generally sound, but very generic, advice.

like image 36
dgvid Avatar answered Oct 11 '22 02:10

dgvid


No, ICollection does not imply an order.

like image 4
afeygin Avatar answered Oct 11 '22 03:10

afeygin


The ICollection instance has the "order" of whatever class that implements it. That is, referencing a List<T> as an ICollection will not alter its order at all.

Likewise, if you access an unordered collection as an ICollection, it will not impose an order on the unordered collection either.

So, to your question:

Does an ICollection even have an order?

The answer is: it depends solely on the class that implements it.

like image 4
James Michael Hare Avatar answered Oct 11 '22 04:10

James Michael Hare