1

I tried to do this:

int listAverage = NumberList.Sum()/NumberList.Length;

where NumberList is an IList. It throws an error:

'System.Collections.Generic.IList' does not contain a definition for 'Length' and no extension method 'Length' accepting a first argument of type 'System.Collections.Generic.IList' could be found (are you missing a using directive or an assembly reference?)

That gets me thinking, why does List<T> not have a Length property? I know you can use Count() instead, but Length has an O(1) time complexity.

Dylan Czenski
  • 1,305
  • 4
  • 29
  • 49
  • 17
    Because it has a `Count` property... – Jeff Mercado Jan 22 '16 at 19:13
  • 1
    `Count` is `O(1)` if the `IList` is actually a list. – Matt Burland Jan 22 '16 at 19:13
  • @AndrewWhitaker: According to the question `NumberList` is an `IList` not a `List`, so while it's probably actually a `List` and is actually `O(1)` (per the docs), it's not necessarily the case. – Matt Burland Jan 22 '16 at 19:15
  • As to why the change in terminology from `Length` to `Count`, you'd have to ask the .NET team. I'm guessing they decided that `Length` didn't really accurately describe the `Count` in some types of collections. – Matt Burland Jan 22 '16 at 19:16
  • 3
    Also FYI [Enumerable.Average](https://msdn.microsoft.com/en-us/library/system.linq.enumerable.average(v=vs.90).aspx) – Timothy Shields Jan 22 '16 at 19:17
  • 2
    My guess is it's because arrays have a length meant to be a fixed number, where a `List`'s count is mutable, and to maybe help differentiate between an array and List. – Drew Kennedy Jan 22 '16 at 19:19
  • @MattBurland: Yep, I accidentally went to the `List` docs – Andrew Whitaker Jan 22 '16 at 19:20
  • @DrewKennedy: Maybe, but you can resize an array with `Array.Resize`, although I believe it's just creating a new array and copying. – Matt Burland Jan 22 '16 at 19:23
  • @MattBurland Yep. This point is exactly why I was careful to say "meant to be a fixed number" :) – Drew Kennedy Jan 22 '16 at 19:24
  • @TimothyShields thanks! That works better. – Dylan Czenski Jan 22 '16 at 19:33
  • @DrewKennedy: It's probably more due to the idea that array and string are continuous, so a `Length` property makes sense. While `Count` comes from `ICollection` and `Count()` is an extension method of `IEnumerable`. It doesn't really make sense to talk about the `Length` of a `Stack` or especially the `Length` of a queue (which could be confused with it's capacity) or the `Length` of a dictionary. So `Count` seems like the more general term to refer to how many things are in a collection. – Matt Burland Jan 22 '16 at 21:46

1 Answers1

3

According to my experience, the convention in .NET seems to be that arrays and strings have the Length property, and higher level countable collections have Count property. The IList<T> has a Count property which is in general should be O(1), but depends on the exact implementation. For example the most used List<T> does it definitely at O(1).

The generic Count() method is an extension for any IEnumerable<T> type, and that has technically O(n) complexity indeed, because the number of items may not be known before enumerating every element, or giving the number requires some custom processing (like for example a Linq to SQL query result expressed by an IQueryable<T> interface).

Matt Booth
  • 1,723
  • 3
  • 13
  • 19
Zoltán Tamási
  • 12,249
  • 8
  • 65
  • 93
  • Can you provide a source that supports your statement "*The convenction in .NET is that arrays and strings have Length, and higher level countable collections have Count property*"? – Jeroen Vannevel Jan 22 '16 at 19:19
  • Okay thanks, I think that might be wisest. While I don't necessarily disagree, I have not yet come across any recommendation or discussion on the topic that would warrant it to be considered a convention. – Jeroen Vannevel Jan 22 '16 at 19:23