Take the 2-minute tour ×

This question already has an answer here:

For a very long time I was curious about the following:

int[] array = new int[1];
int iArrayLength = array.Length;    //1

Since arrays implement the IList interface, the following is allowed:

int iArrayCount = ((IList<int>)array).Count;    //still 1


int iArrayCount = array.Count;  //Compile error. WHY?
int iArrayLength = array.Length;    //This is what we learned at school!

The question: How can an array implement IList<T> (especially the int Count { get; } property from IList<T>) without allowing it to be used on the base class?

share|improve this question

marked as duplicate by nawfal, Fox32, Jesse, Luca Geretti, Daniel Mann May 12 '13 at 16:56


You could probably simulate this yourself by shadowing the 'Count' property from the base class in your own inherited class, and make it private instead. VB.NET has an explicit keyword 'Shadows' for this, not sure about C#, thoug. –  Joachim VR Sep 17 '12 at 14:28
You're title is mistakable. Arrays actually implement Count from ICollection: int ICollection.Count { get { return this.Length; } } –  Tim Schmelter Sep 17 '12 at 14:29
@TimSchmelter but IList<T> inherits from ICollection<T>; ICollection<T> also has a Count property, so all types implementing IList<T> must also implement ICollection<T>.Count. True, the property is not defined in IList<T>, but the question is a reasonable one. –  phoog Sep 17 '12 at 14:36
@phoog: Apart of the fact that it's not a property of IList, it is implemented in Array, that was the main reason why i said that the title is mistakable ("..without implementing.."). –  Tim Schmelter Sep 17 '12 at 14:44
@TimSchmelter aha, I see, I misunderstood your point. But if you read the title from the perspective of not knowing about explicit interface implementation, the question makes perfect sense. ("Mistaken", by the way, not "mistakable"). –  phoog Sep 17 '12 at 15:00

2 Answers 2

up vote 28 down vote accepted

This is known as an explicit interface member implementation. The interface member is not exposed as a public member of the type, but it is available by casting the reference to the interface type.

This can be done in C# like this:

interface I
    void M();

class C : I
    public int P { get; set; }
    void I.M() { Console.WriteLine("M!"); }

Then you can use these types like this:

C obj = new C();
obj.P = 3;

But this won't compile:


As JeffN825 notes, one reason for implementing the interface members explicity is that they're not supported by the type. For example, Add throws an exception (relevant discussion). Another reason for implementing a member explicity is that it duplicates another public member with a different name. That's the reason Count is implemented explicitly; the corresponding public member is Length. Finally, some members are implemented implicitly, namely, the indexer. Both of these lines work (assuming arr is an array of int):

arr[0] = 8;
((IList<int>)arr)[0] = 8;
share|improve this answer
"explicit interface member definition" a good keyword for google! I didn't know about it, thanks! It's interesting that is doesn't have any access modifier. So you can use your internal interfaces on public classes without having to implement all methods/properties as public, nice! –  Gerrit Sep 17 '12 at 14:35
@Gerrit; actually, that's incorrect. It should be "explicit interface member implementation." I have corrected. –  phoog Sep 17 '12 at 14:37
@Gerrit Eric Lippert has an interesting discussion about using internal interfaces on public types here: blogs.msdn.com/b/ericlippert/archive/2011/12/08/… –  phoog Sep 17 '12 at 14:40
@Gerrit Jon Skeet's extremely thorough answer here gives much more detail than mine: stackoverflow.com/a/11163336/385844 –  phoog Sep 17 '12 at 14:55
@phoog Interesting link. Fascinating reading the Jon vs Hans debate :) –  Simon Whitehead Jan 25 '13 at 3:36

Because an Array doesn't support all of the features of an IList (Add/Remove/etc), IList.Count (and several other methods) are all implemented privately (explicitly). You can see this in disassembly:

int ICollection.Count

If you really wanted to use Count, you could do

share|improve this answer
