Why does C# array not have Count property? [duplicate]
Asked Answered
S

4

12

Possible Duplicate:
count vs length vs size in a collection

Really strange:

C# arrays such as the following

double[] test = new double[1];

support the Length property to get the size of the array. But arrays also implement an IList interface:

IList<double> list = test;

However, the IList interface provides also a Count property. How come the array ("test" in this case) doesn't?

Edit: Thanks to all of you who pointed out that it is in fact the ICollection interface (not IList) which provides the Count property, and also that this is due to explicit implementation of the interface.

Singapore answered 22/1, 2011 at 19:13 Comment(1)
... vs Capacity vs ItemCount (like ColumnCount in ListView vs Columns.Count) vs NumItems (NumIndices in EnvDTE) vs CountOfItems (CountOfLines in EnvDTE) vs etc ... I just love the consistency in MS's frameworks. :)Refugiorefulgence
R
18

Simply, they chose to call it Length, and implement Count via explicit interface implementation -something like:

int ICollection.Count { get { return Length; } }
Retuse answered 22/1, 2011 at 19:16 Comment(3)
+1 from me, but I'm guessing maybe they were looking for an answer to the "why" part?Refugiorefulgence
@mehrdad - I wish I had my annotated spec on me :(Retuse
Thanks for pointing me to explicit interface implementations - had no idea that such things exist ;-)Singapore
L
9

It was a design choice about Naming, not semantics.

Arrays have a Length property, as does the String.

Length signals immutable: You cannot Add to or Remove from an array.

Lists and other containers have a Count property that can usually change.

Oh, and if you call list.Append(1.1); you will get a not supported exception.

Lorikeet answered 22/1, 2011 at 19:16 Comment(2)
Length by no means signals immutable; MemoryStream (actually, lots of stream implementations), StringBuilder, etcRetuse
@Marc: I didn't mean to imply a very strict rule. Streams are another domain, and I think StringBuilder.Length is a concession to String. I still think it loosely holds for containers.Lorikeet
S
5

Types inheriting from Array obtain implementations of IList<T> at run-time (how this is possible, don't ask me):

In the .NET Framework version 2.0, the Array class implements the System.Collections.Generic.IList<T>, System.Collections.Generic.ICollection<T>, and System.Collections.Generic.IEnumerable<T> generic interfaces. The implementations are provided to arrays at run time, and therefore are not visible to the documentation build tools. As a result, the generic interfaces do not appear in the declaration syntax for the Array class, and there are no reference topics for interface members that are accessible only by casting an array to the generic interface type (explicit interface implementations). The key thing to be aware of when you cast an array to one of these interfaces is that members which add, insert, or remove elements throw NotSupportedException.

In effect the IList<T> implementation acts like an explicit implementation, as Marc explained in his answer. This is why you can access certain members of IList<T> from the result of a cast but not from a variable typed as T[] specifically.

Schlep answered 22/1, 2011 at 19:17 Comment(2)
That last line was in essence already in the question.Lorikeet
@Henk: You're right; I meant to highlight the "explicit implementation" part; including the code example was superfluous and only distracted from that point. I removed it.Schlep
C
5

The Count property is hidden using the explicit interface declaration style, for example like this in a class definition:

int IList.Count {
    get {
        // ...etc...
    }
}

You can access methods and properties hidden like this using a type cast, e.g.

((IList<double>) myArray).Count
Colman answered 22/1, 2011 at 19:18 Comment(5)
IList doesn't actually define Count; ICollection doesRetuse
@Marc: The way that interfaces inherit makes that rather moot.Lorikeet
@Henk - I'd need to check, but does it compile if you get it wrong? I didn't think so...Retuse
@Henk - tested: "Error 1 'IList.Count' in explicit interface declaration is not a member of interface" - so the compiler doesn't think it is a moot point.Retuse
@Marc: right. my mistake. I was thinking how Reflector sometimes shuffles if-members around.Lorikeet

© 2022 - 2024 — McMap. All rights reserved.