wkempf said:
dpratt71 said:
*snip*
There are complexity guarantees documented on the various interfaces here.  Exposing an IEnumerable<T> means that a large number of operations consumers are going to want to perform are going to have O(N) complexity.  LINQ may "cheat" and give you better performance, but the complexity that consumers MUST assume is O(N).  Now, expose a ReadOnlyCollection<T>, and most of those same operations are now O(1).  A hypothetical IReadOnlyCollection would provide the same complexity guarantees you have with ReadOnlyCollection<T>, but without the existense of mutating methods, making for a "cleaner" design.  Again, though, in practice the current design is "good enough", and certainly preferable to IEnumerable<T>.

Up 'til now, you were making some sense Wink

"There are complexity guarantees documented on the various interfaces here. "

Where is this documentation of which you speak and how does it even make sense for an interface to guarantee something that is wholly dependent on the implementation.

"Exposing an IEnumerable<T> means that a large number of operations consumers are going to want to perform are going to have O(N) complexity.  LINQ may "cheat" and give you better performance, but the complexity that consumers MUST assume is O(N)."

I think this is a bogus argument. To make an analogy, if you came from the world of functional programming, it might shock you to learn that something as innocuous as this:

    int DoStuff(int value);

may very well "launch the missiles", so to speak. This does not mean that the imperative programmer MUST assume that he or she may very well start WWIII with the next method call.

"Now, expose a ReadOnlyCollection<T>, and most of those same operations are now O(1)."

As has been pointed out at least a couple times on this thread, ReadOnlyCollection delegates such operations to the wrapped IList. Given that I can wrap *anything* that implements IList, how is ReadOnlyCollection going to guarantee the complexity?