3

The System.Array class implements ICollection interface. This interface has a public property called Count which gives the number of elements in the array.

Suppose I declare an Array and access its properties

Array numbers = Array.CreateInstance(typeof(int), 10);
Console.WriteLine(numbers.Count);

You would expect to see 10 on the screen. But, I am not able to see Count property after putting a period after numbers. There is however, a property called Length. Why is it so?

Update: This is because of Explicit Interface Implementation. Since there is another question similar to mine, I decided to re-word it. Why was the design decision taken to explicitly implement this particular property? There is another property with the same functionality Length. So why go through the trouble of providing the explicitly implemented Count?

TheSilverBullet
  • 605
  • 7
  • 21
  • Cast it to `ICollection`. – Tim Schmelter Feb 20 '13 at 09:37
  • Why aren't you using `int[] number = new int[10];` ? – PhonicUK Feb 20 '13 at 09:37
  • @PhonicUK, The method I am using is also a valid way of declaring an `Array`. Is there any reason to prefer the syntax you have mentioned? – TheSilverBullet Feb 20 '13 at 10:00
  • 1
    @TheSilverBullet It's ok to use `Array.CreateInstance`, but you should not use `Array` type to work with arrays. If you try to access elements of this array, you will get `object` instead of `int32`. This will cause boxing http://msdn.microsoft.com/en-us/library/yz2be5wk(v=vs.80).aspx .Boxing is bad – Dmitrii Dovgopolyi Feb 20 '13 at 11:24

4 Answers4

4

You need to cast it to ICollection.

Array.ICollection.Count Property

This member is an explicit interface member implementation. It can be used only when the Array instance is cast to an ICollection interface.

Btw, here is a duplicate: I can not access Count property of the array but through casting to ICollection !

Update:

This is because of Explicit Interface Implementation. Since there is another question similar to mine, I decided to re-word it. Why was the design decision taken to explicitly implement this particular property? There is another property with the same functionality Length. So why go through the trouble of providing the explicitly implemented Count?

It inherits it from IList<T> which implements ICollection<T>. So you could ask instead why array implements IList?.

Community
  • 1
  • 1
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • "It inherits it from `IList`..." As far as I know `Array` doesn't inherit from `List`. Am I missing something here? And thanks for the link. Learnt something valuable from the discussions there. – TheSilverBullet Feb 20 '13 at 11:38
  • 1
    @TheSilverBullet: In C# 2.0 and later, single-dimensional arrays that have a lower bound of zero automatically implement `IList`. http://msdn.microsoft.com/en-us/library/ms228502(v=vs.110).aspx – Tim Schmelter Feb 20 '13 at 11:48
  • The link you have provided is extremely helpful and it led me to re-read some portion of interface design for list. I would also like to ask why the decision to automatically implement `IList` was taken. But I right now prefer to leave it for another day. I wish I could accept your question as well... – TheSilverBullet Feb 21 '13 at 10:21
2

System.Array class implements ICollection interface explicitly. You can use methods of ICollection only after casting Array to ICollection

Array numbers = Array.CreateInstance(typeof(int), 10);
ICollection numbersCollection =  (ICollection)numbers;
Console.WriteLine(numbersCollection.Count);

Implicit and Explicit Interface Implementations

System.Array.Count actually uses Array.Length property

int ICollection.Count
{
    get
    {
        return this.Length;
    }
}
Dmitrii Dovgopolyi
  • 6,231
  • 2
  • 27
  • 44
1

Count is implemented explicitly from the ICollection interface. That's why it is invisible. You will have to cast ((ICollection) numbers).Count in order to get access to the Count property.

Ryszard Dżegan
  • 24,366
  • 6
  • 38
  • 56
  • 1
    Thanks, yBee. The thing is once you use the syntax to typecast the array variable, you will not be prompted for any properties. I had to type in `Count` and it worked. Why do you think it is like this? – TheSilverBullet Feb 20 '13 at 09:42
  • 1
    @TheSilverBullet: Why `Count` is explicit? Why there is `Length` instead? Programmers are accustomed that when we are speaking about an array, we are speaking about `Length`. But in the other hand, there is an extension method for `IEnumerable` called `Count()` that in fact returns `Length` if operate on array. So probably you should use here `IEnumerable.Count()` instead casting to `ICollection`. – Ryszard Dżegan Feb 20 '13 at 09:47
1

I think this is not a question of programming, it's a question of logical intension.

You might ask yourself with these two questions:

Q1. Are arrays collections?

Q2. Are collections arrays?

In c#, the existing implemention tells that the answer of Q1 is:

A1: Yes, arrays are collections. Therefor Array implements ICollection.

And what about Q2? It's a similar question to ask is a horse a white horse? You might want to take a look of [When a white horse is not a horse] for the answer.

With Q2, I would reply with: "I don't know, it's according to the context." So, what are the possibly contexts? If you passed an array as an interface implements ICollection, then yes, this collection is also an array. However, you might pass a different object except an array with an identical interface. Then, does it necessarily been an array? If you are interested in some extension of this, A3 in [this answer] might get you the idea.

Thus, it's totally reasonable, Array has the Length property and also has the Count property which is from explicit implementation of ICollection.

Community
  • 1
  • 1
Ken Kin
  • 4,503
  • 3
  • 38
  • 76
  • This answer was helpful in an entirely different way as compared to other answers. The reason behind me questioning the intension is only because I want to dig out some real live design decisions and understand why it was done the way it was done. – TheSilverBullet Feb 21 '13 at 10:10