Groups | Blog | Home
all groups > c# > april 2006 >

c# : Does ReadOnlyCollection<T> implement IList<T> ?



Lucian Wischik
4/1/2006 12:57:36 PM
Does ReadOnlyCollection<T> really implement IList<T>, like it claims
to do? ...


When I right-click on ReadOnlyCollection and look at its definition,
it says this:

public class ReadOnlyCollection<T>
: IList<T>,ICollection<T>,IEnumerable<T> ...

However, the following code fails its assertion check:

List<string> xs = new List<string>();
ReadOnlyCollection<string> ro = new ReadOnlyCollection<string>(xs);
IList<string> il = ro as IList<string>;
Debug.Assert(il != null);

I don't understand how this is possible. If ReadOnlyCollection<T>
claims to implement IList<T>, then I should be able to cast to it,
shouldn't I?


In a similar vein, the following code fails to compile because, it
claims, ReadOnlyCollection<string> doesnt implement the Insert method.
How is this possible? Insert is part of IList<T>, which
ReadOnlyCollection<T> inherits from, so it should be there!

ro.Insert(0,"hello");



I'm asking these questions because I want to create my own
wrapper-class, similar to how ReadOnlyCollection is a wrapper around
an IList. I need to understand which interfaces I should declare
myself as providing. And so I need to understand why
ReadOnlyCollection declares that it supports the interfaces it does,
and how.

I wonder if ReadOnlyCollection really does implement those interfaces,
but somehow *hides* the Insert method &c.? How is this done in C#? The
documentation specifically says that methds from interfaces must be
public, so I don't know.


--
Lucian Wischik
4/1/2006 1:25:57 PM
[quoted text, click to view]

Okay, I understand now. Thanks for the prompt and helpful answer.


[quoted text, click to view]

No -- it was a mistake on my part, caused by stopping the debugger AT
the cast rather than after it.

--
Jon Skeet [C# MVP]
4/1/2006 10:11:35 PM
[quoted text, click to view]

Could you post a short but complete program that demonstrates that?
Here's one which seems to go against it:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

class Test
{
static void Main()
{
List<string> xs = new List<string>();
ReadOnlyCollection<string> ro =
new ReadOnlyCollection<string>(xs);
IList<string> il = ro as IList<string>;
Console.WriteLine (il != null);
}
}

That prints out "True" as expected.

[quoted text, click to view]

No, it shouldn't - ReadOnlyCollection implements IList<T>.Insert
explicitly, so it's only "there" when you're using the
ReadOnlyCollection as an IList<T>. In other words, you can do:

((IList<T>)ro).Insert (0, "hello");

[quoted text, click to view]

Search for "explicit interface implementation". Basically, instead of:

public void MethodName(...);

you do

void InterfaceName.MethodName(...);

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
AddThis Social Bookmark Button