evildictaitor said:
wkempf said:
*snip*
You're reading too much into the "reply to" box from C9. I was just commenting on the whole thread, not just replying to you.

My point about why Count isn't there was a response to TommyCarlier who explictly lamented the fact that it's not there by default on an IEnumerable<T>.

The optimisation you mention of casting to an ICollection<T> is fine, because it first checks that the cast is valid, and ensures that if the cast is valid that it doesn't mutate the collection - my point was more general and related to CannotResolveSymbol's post who noted that exposing IEnumerable<T> isn't a guarrantee that the inner property won't be mutated by the caller.

You say that noone was suggesting you wrap the collection in a ReadOnlyCollection, but W3bbo's code example does exactly that, so your point is invalid.

Please don't take the C9 "reply to" as nessisarrilly a refutation of what you said. I just clicked on the reply closest to the bottom of the screen, and I meant nothing by it.


Edit: I note actually that the order complexity of ReadOnlyCollection isn't O(_val.Count), but actually a minor overhead, since the ReadOnlyCollection defers all of the accesses of the list to the contained list and throws an exception on all mutation attempts, so it's not quite as bad as I made it sound.

Actually, I didn't say (or mean) that I wanted IEnumerable<T> to have a Count-property: IEnumerable<T> is perfectly fine the way it is. I myself have recently writen a tokenizer that has a method ReadAll which returns an IEnumerable<T> that lazily reads from a TextReader and produces tokens. In this case, a Count-property would mean that all the tokens would have to be read before anything can be done.

What I want is that there was an interface IReadOnlyCollection<T> or ICountEnumerable<T> the my classes can expose in cases where my classes know the number of elements. I never indicated index-based random access. In fact, read-only index-based random access could also be exposed as an interface IRandomAccessEnumerable<T>. Adding these 2 additional interfaces would not break existing code (because the existing code would not know about them). The interface hierarchy would then look like this:

public
 interface IEnumerable<T> : IEnumerable { IEnumerator<T> GetEnumerator(); } public interface ICountEnumerable<T> : IEnumerable<T> { int Count { get; } } public interface IRandomAccessEnumerable<T> : ICountEnumerable<T> { T this[int index] { get; } } public
 interface ICollection<T> : ICountEnumerable<T> { void Add(T item); void Clear(); bool Contains(T item); void CopyTo(T[] array, int arrayIndex); bool Remove(T item); bool IsReadOnly { get; } } public interface IList<T> : ICollection<T>, IRandomAccessEnumerable<T>
 { int IndexOf(T item); void Insert(int index, T item); void RemoveAt(int index); T this[int index] { get; set; } }